docs.sheetjs.com/docz/docs/03-demos/23-data/19-alasql.md

337 lines
8.8 KiB
Markdown
Raw Normal View History

2023-02-24 07:46:48 +00:00
---
2023-12-05 03:46:54 +00:00
title: Sheets with AlaSQL
sidebar_label: AlaSQL
2024-03-18 08:24:41 +00:00
pagination_prev: demos/cli/index
2023-02-28 11:40:44 +00:00
pagination_next: demos/local/index
2023-02-24 07:46:48 +00:00
sidebar_custom_props:
sql: true
---
2023-04-09 21:13:24 +00:00
<head>
<script src="/alasql/alasql.js"></script>
</head>
2023-02-24 07:46:48 +00:00
import current from '/version.js';
2023-04-29 11:21:37 +00:00
import CodeBlock from '@theme/CodeBlock';
2023-02-24 07:46:48 +00:00
2023-08-20 20:39:35 +00:00
[AlaSQL](https://alasql.org/) is a pure JavaScript in-memory SQL database. It
has built-in support for SheetJS through the `XLSX` target operator.
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
data from spreadsheets.
2023-02-24 07:46:48 +00:00
This demo covers basic concepts pertaining to data import and export. The
official documentation includes advanced examples and deployment tips as well as
strategies for general data processing in AlaSQL expressions.
2023-11-28 07:05:59 +00:00
:::note Tested Deployments
2023-04-09 21:13:24 +00:00
This demo was tested in the following environments:
| Environment | AlaSQL | Date |
|:--------------------|:-------|:----------:|
2023-12-05 03:46:54 +00:00
| NodeJS | 3.1.0 | 2023-12-04 |
| Standalone (Chrome) | 3.1.0 | 2023-12-04 |
2023-04-09 21:13:24 +00:00
:::
## Live Demo
2024-04-26 04:16:13 +00:00
This demo fetches https://docs.sheetjs.com/pres.numbers, performs a `SELECT`
query using the built-in AlaSQL + SheetJS integration, then displays the result.
Using the result as a data source, the demo will write to a new spreadsheet.
2023-04-09 21:13:24 +00:00
<details>
<summary><b>Demo AlaSQL Queries</b> (click to show)</summary>
2023-04-09 21:13:24 +00:00
```sql title="AlaSQL Query for reading data from a workbook"
SELECT `Index`, -- "Index" field is the "Index" column of the sheet
UPPER(`Name`) AS `Nom` -- "Nom" field will be uppercase of "Name" column
FROM XLSX(?, { -- Parse the workbook bytes passed to alasql.promise
autoExt: false -- This option is required in the browser
})
```
```sql title="AlaSQL Query for writing data to a workbook"
SELECT * -- use every field from every row in dataset
INTO XLSX( -- export data to file
"SheetJSAlaSQL.xlsx" -- filename for export
) FROM ?
```
</details>
2023-09-24 03:59:48 +00:00
:::caution pass
2023-04-09 21:13:24 +00:00
If the live demo shows a message
```
alasql undefined
```
please refresh the page. This is a known bug in the documentation generator.
:::
```jsx live
function SheetJSAlaSQL() {
const q1 = "SELECT `Index`, UPPER(`Name`) AS `Nom` FROM XLSX(?,{autoExt:false})";
const q2 = `SELECT * INTO XLSX("SheetJSAlaSQL.xlsx") FROM ?`;
2024-04-26 04:16:13 +00:00
const url = "https://docs.sheetjs.com/pres.numbers";
2023-04-09 21:13:24 +00:00
const [rows, setRows] = React.useState([]);
const loadURL = React.useCallback(async() => {
if(typeof alasql=="undefined") return setRows([{Nom:"alasql undefined"}]);
const blob = await (await fetch(url)).blob();
const data = URL.createObjectURL(blob);
2023-04-18 20:26:59 +00:00
const res = await alasql.promise(q1,[data]);
2023-04-09 21:13:24 +00:00
setRows(res);
await alasql.promise(q2, [res]);
}, []);
return ( <>
<pre><b>URL: </b>{url}<br/><b>Import: </b>{q1}<br/><b>Export: </b>{q2}</pre>
<table><tr><th>Index</th><th>Nom</th></tr>
{rows.map(({Nom, Index}) => <tr><td>{Index}</td><td>{Nom}</td></tr>)}
</table>
<button onClick={loadURL}>Click to start</button>
</> );
}
```
## Browser
#### Standalone Scripts
2023-09-22 06:32:55 +00:00
The [SheetJS Standalone scripts](/docs/getting-started/installation/standalone)
should be loaded before the `alasql` script:
2023-04-09 21:13:24 +00:00
2023-05-07 13:58:36 +00:00
<CodeBlock language="html">{`\
2023-04-27 09:12:19 +00:00
<script src="https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js"></script>
<script src="https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/alasql"></script>`}
2023-05-07 13:58:36 +00:00
</CodeBlock>
2023-04-09 21:13:24 +00:00
#### Frameworks and Bundlers
`alasql` uses an older version of the library. It can be overridden through a
`package.json` override. The lines should be added *before* installing `alasql`:
2023-05-07 13:58:36 +00:00
<CodeBlock language="json">{`\
2023-04-09 21:13:24 +00:00
{
/* add this part before "name" */
/* highlight-start */
"overrides": {
"xlsx": "https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz"
},
/* highlight-end */
"name": "my-project",
/* ... more fields ... */
`}
2023-05-07 13:58:36 +00:00
</CodeBlock>
2023-04-09 21:13:24 +00:00
After adding the override, AlaSQL can be installed through `npm`:
```bash
2023-05-07 13:58:36 +00:00
npm i --save alasql
2023-04-09 21:13:24 +00:00
```
In imports, the SheetJS library must be passed to AlaSQL as shown below:
```js
import * as alasql from 'alasql';
import * as XLSX from 'xlsx';
alasql.utils.isBrowserify = false;
alasql.utils.global.XLSX = XLSX;
```
### Reading Files
The `XLSX` "from" target expects a filename. In the browser, AlaSQL uses object
URLs which can be created from `Blob` or `File` objects.
The following snippet fetches data and passes to AlaSQL:
```js
2024-04-26 04:16:13 +00:00
const blob = await (await fetch("https://docs.sheetjs.com/pres.numbers")).blob();
2023-04-19 20:03:23 +00:00
const data = URL.createObjectURL(blob);
2023-04-09 21:13:24 +00:00
const res = await alasql.promise("SELECT * FROM XLSX(?, {autoExt: false}", [data]);
```
By default, the `XLSX` "from" target automatically adds a `.xlsx` extension. To
read URLs, the `autoExt: false` option should be passed as the second argument:
```sql
SELECT `Name`, `Index` FROM XLSX(
? --<< this will be the URL passed into `alasql.promise`
// highlight-start
, { --<< options are supplied as the second argument to XLSX operator
autoExt: false --<< do not automatically add ".xlsx" extension!
}
// highlight-end
) WHERE `Index` < 45
```
By default the workbook is parsed and `sheet_to_json` is used to pull data:
```js
(async() => {
2024-04-26 04:16:13 +00:00
const blob = await (await fetch("https://docs.sheetjs.com/pres.numbers")).blob();
2023-04-19 20:03:23 +00:00
const data = URL.createObjectURL(blob);
2023-04-09 21:13:24 +00:00
const aoo = await alasql.promise("SELECT * FROM XLSX(?, {autoExt: false}", [data]);
console.log(aoo); // [ { Name: "Bill Clinton", Index: 42 }, ...]
})();
```
### Writing Files
The `XLSX` "into" target calls `XLSX.writeFile` under the hood:
```js
(async() => {
const data = [
{ Name: "Bill Clinton", Index: 42 },
2023-12-05 03:46:54 +00:00
{ Name: "SheetJS Dev", Index: 47 }
2023-04-09 21:13:24 +00:00
];
2023-05-27 23:07:45 +00:00
await alasql.promise(`SELECT * INTO XLSX("PresMod5.xlsx") FROM ?`, [data]);
2023-04-09 21:13:24 +00:00
/* PresMod5.xlsx will be created */
})();
```
## NodeJS
2023-02-24 07:46:48 +00:00
2023-09-24 03:59:48 +00:00
:::caution pass
2023-02-24 07:46:48 +00:00
`alasql` uses an older version of the library. It can be overridden through a
`package.json` override in the latest versions of NodeJS:
2023-05-07 13:58:36 +00:00
<CodeBlock language="json">{`\
2023-02-24 07:46:48 +00:00
{
"overrides": {
"xlsx": "https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz"
}
}`}
2023-05-07 13:58:36 +00:00
</CodeBlock>
2023-02-24 07:46:48 +00:00
:::
2023-04-09 21:13:24 +00:00
### Reading Files
2023-02-24 07:46:48 +00:00
By default, the `XLSX` "from" target automatically adds a `.xlsx` extension. To
read files with an arbitrary filename, the `autoExt: false` option should be
passed as the second argument:
```sql
SELECT `Name`, `Index` FROM XLSX(
"pres.numbers" --<< filename is "pres.numbers"
// highlight-start
, { --<< options are supplied as the second argument to XLSX operator
autoExt: false --<< do not automatically add ".xlsx" extension!
}
// highlight-end
) WHERE `Index` < 45
```
By default the workbook is parsed and `sheet_to_json` is used to pull data:
```js
const { promise: alasql } = require("alasql");
(async() => {
2023-04-09 21:13:24 +00:00
const aoo = await alasql(`SELECT * from XLSX("pres.xlsx", {autoExt: false})`);
2023-02-24 07:46:48 +00:00
console.log(aoo); // [ { Name: "Bill Clinton", Index: 42 }, ...]
})();
```
2023-04-09 21:13:24 +00:00
### Writing Files
2023-02-24 07:46:48 +00:00
The `XLSX` "into" target calls `XLSX.writeFile` under the hood:
```js
const { promise: alasql } = require("alasql");
(async() => {
const data = [
{ Name: "Bill Clinton", Index: 42 },
2023-12-05 03:46:54 +00:00
{ Name: "SheetJS Dev", Index: 47 }
2023-02-24 07:46:48 +00:00
];
2023-04-09 21:13:24 +00:00
await alasql(`SELECT * INTO XLSX("PresMod5.xlsx") FROM ?`, [data]);
/* PresMod5.xlsx will be created */
2023-02-24 07:46:48 +00:00
})();
```
### NodeJS Example
1) Create an empty folder for the project:
```bash
mkdir alasql
cd alasql
```
2) In the folder, create a stub `package.json` with the `xlsx` override:
2023-04-29 11:21:37 +00:00
<CodeBlock language="json" title="package.json">{`\
2023-02-24 07:46:48 +00:00
{
"overrides": {
2023-04-29 11:21:37 +00:00
"xlsx": "https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz"
2023-02-24 07:46:48 +00:00
}
2023-04-29 11:21:37 +00:00
}`}
</CodeBlock>
2023-02-24 07:46:48 +00:00
3) Install SheetJS and AlaSQL:
2023-04-29 11:21:37 +00:00
<CodeBlock language="bash">{`\
npm i --save alasql@3.1.0 https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
</CodeBlock>
2023-02-24 07:46:48 +00:00
2024-04-26 04:16:13 +00:00
4) Download the test file https://docs.sheetjs.com/pres.numbers :
2023-02-24 07:46:48 +00:00
```bash
2024-04-26 04:16:13 +00:00
curl -LO https://docs.sheetjs.com/pres.numbers
2023-02-24 07:46:48 +00:00
```
5) Save the following test script to `SheetJSAlaSQL.js`:
```js title="SheetJSAlaSQL.js"
const { promise: alasql } = require("alasql");
(async() => {
/* read data from spreadsheet to JS */
const data = await alasql(`
SELECT \`Name\`, \`Index\`
FROM XLSX("pres.numbers", {autoExt:false})
WHERE \`Index\` < 45
`);
console.log(data);
/* write data from JS to spreadsheet */
2023-12-05 03:46:54 +00:00
data.push({ Name: "SheetJS Dev", Index: 47 });
2023-02-24 07:46:48 +00:00
await alasql(`SELECT * INTO XLSX("SheetJSAlaSQL1.xlsx") FROM ?`, [data]);
})();
```
6) Run the test script
```bash
node SheetJSAlaSQL.js
```
The output should display:
2023-05-07 13:58:36 +00:00
```js
2023-02-24 07:46:48 +00:00
[
{ Name: 'Bill Clinton', Index: 42 },
{ Name: 'GeorgeW Bush', Index: 43 },
{ Name: 'Barack Obama', Index: 44 }
]
```
The script should generate `SheetJSAlaSQL1.xlsx` with the additional row:
```csv
Name,Index
Bill Clinton,42
GeorgeW Bush,43
Barack Obama,44
2023-12-05 03:46:54 +00:00
SheetJS Dev,47
2023-02-24 07:46:48 +00:00
```