dp
This commit is contained in:
parent
734f70e6d9
commit
4c92216ebe
@ -1,4 +1,6 @@
|
||||
---
|
||||
pagination_prev: getting-started/index
|
||||
pagination_next: getting-started/example
|
||||
sidebar_position: 1
|
||||
sidebar_custom_props:
|
||||
summary: Classic pages with simple <script> tags
|
||||
|
@ -1,4 +1,6 @@
|
||||
---
|
||||
pagination_prev: getting-started/index
|
||||
pagination_next: getting-started/example
|
||||
sidebar_position: 2
|
||||
sidebar_custom_props:
|
||||
summary: Angular, React, VueJS, Webpack, etc.
|
||||
|
@ -1,4 +1,6 @@
|
||||
---
|
||||
pagination_prev: getting-started/index
|
||||
pagination_next: getting-started/example
|
||||
sidebar_position: 3
|
||||
sidebar_custom_props:
|
||||
summary: Import ECMAScript Modules and TypeScript definitions
|
||||
|
@ -1,4 +1,6 @@
|
||||
---
|
||||
pagination_prev: getting-started/index
|
||||
pagination_next: getting-started/example
|
||||
sidebar_position: 4
|
||||
sidebar_custom_props:
|
||||
summary: Server-side and other frameworks using NodeJS modules
|
||||
|
@ -1,4 +1,6 @@
|
||||
---
|
||||
pagination_prev: getting-started/index
|
||||
pagination_next: getting-started/example
|
||||
sidebar_position: 5
|
||||
sidebar_custom_props:
|
||||
summary: Photoshop, InDesign, and other Creative Cloud apps
|
||||
|
@ -1,4 +1,6 @@
|
||||
---
|
||||
pagination_prev: getting-started/index
|
||||
pagination_next: getting-started/example
|
||||
sidebar_position: 6
|
||||
sidebar_custom_props:
|
||||
summary: NetSuite, SAP UI5, RequireJS
|
||||
|
@ -1,4 +1,6 @@
|
||||
---
|
||||
pagination_prev: getting-started/index
|
||||
pagination_next: getting-started/example
|
||||
sidebar_position: 7
|
||||
sidebar_custom_props:
|
||||
summary: Download and Import ECMAScript Modules
|
||||
|
@ -1,4 +1,5 @@
|
||||
---
|
||||
pagination_prev: getting-started/index
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
---
|
||||
hide_table_of_contents: true
|
||||
pagination_next: getting-started/example
|
||||
---
|
||||
|
||||
# Getting Started
|
||||
|
@ -27,12 +27,6 @@ suitable for a number of libraries. When more advanced shapes are needed,
|
||||
it is easier to munge the output of an array of arrays.
|
||||
|
||||
|
||||
### Tabulator
|
||||
|
||||
[Tabulator](http://tabulator.info/docs/5.3/download#xlsx) includes deep support
|
||||
through a special Export button. It handles the SheetJS-related operations.
|
||||
|
||||
|
||||
### x-spreadsheet
|
||||
|
||||
With a familiar UI, [`x-spreadsheet`](https://myliang.github.io/x-spreadsheet/)
|
||||
@ -206,6 +200,13 @@ many additional features including massive data streaming, sorting and styling.
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
### Tabulator
|
||||
|
||||
[Tabulator](http://tabulator.info/docs/5.3/download#xlsx) includes deep support
|
||||
through a special Export button. It handles the SheetJS-related operations.
|
||||
|
||||
|
||||
### Angular UI Grid
|
||||
|
||||
:::warning
|
||||
|
@ -414,4 +414,144 @@ The response should show the data in CSV rows.
|
||||
|
||||
It should prompt to download `SheetJSNest.xlsx`
|
||||
|
||||
</details>
|
||||
</details>
|
||||
|
||||
### Fastify
|
||||
|
||||
:::note
|
||||
|
||||
This demo was verified on 2022 August 24 using `fastify@4.5.2`
|
||||
|
||||
:::
|
||||
|
||||
_Reading Data_
|
||||
|
||||
`@fastify/multipart`, which uses `busbuy` under the hood, can be registered:
|
||||
|
||||
```js
|
||||
/* load SheetJS Library */
|
||||
const XLSX = require("xlsx");
|
||||
/* load fastify and enable body parsing */
|
||||
const fastify = require('fastify')({logger: true});
|
||||
// highlight-next-line
|
||||
fastify.register(require('@fastify/multipart'), { attachFieldsToBody: true });
|
||||
```
|
||||
|
||||
Once registered with the option `attachFieldsToBody`, route handlers can use
|
||||
`req.body` directly:
|
||||
|
||||
```js
|
||||
/* POST / reads submitted file and exports to requested format */
|
||||
fastify.post('/', async(req, reply) => {
|
||||
/* "file" is the name of the field in the HTML form*/
|
||||
const file = req.body.upload;
|
||||
/* toBuffer returns a promise that resolves to a Buffer */
|
||||
// highlight-next-line
|
||||
const buf = await file.toBuffer();
|
||||
/* `XLSX.read` can read the Buffer */
|
||||
const wb = XLSX.read(buf);
|
||||
/* reply with a CSV */
|
||||
reply.send(XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]]));
|
||||
});
|
||||
```
|
||||
|
||||
:::caution
|
||||
|
||||
Out of the box, Fastify will return an error `FST_ERR_CTP_BODY_TOO_LARGE` when
|
||||
processing large spreadsheets (`statusCode 413`). This is a Fastify issue.
|
||||
|
||||
[`bodyLimit`](https://www.fastify.io/docs/latest/Reference/Server/#bodylimit)
|
||||
in the docs explains the setting. It can be overridden during server creation:
|
||||
|
||||
```js
|
||||
/* increase request body size limit to 5MB = 5 * 1024 * 1024 bytes */
|
||||
const fastify = require('fastify')({bodyLimit: 5 * 1024 * 1024});
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
_Writing Data_
|
||||
|
||||
The `Content-Disposition` header must be set manually:
|
||||
|
||||
```js
|
||||
/* GET / returns a workbook */
|
||||
fastify.get('/', (req, reply) => {
|
||||
/* make a workbook */
|
||||
var wb = XLSX.read("S,h,e,e,t,J,S\n5,4,3,3,7,9,5", {type: "binary"});
|
||||
|
||||
/* write to Buffer */
|
||||
const buf = XLSX.write(wb, {type:"buffer", bookType: "xlsx"});
|
||||
|
||||
/* set Content-Disposition header and send data */
|
||||
// highlight-next-line
|
||||
reply.header('Content-Disposition', 'attachment; filename="SheetJSFastify.xlsx"').send(buf);
|
||||
});
|
||||
```
|
||||
|
||||
<details><summary><b>Testing</b> (click to show)</summary>
|
||||
|
||||
0) Save the following snippet to `SheetJSFastify.js`:
|
||||
|
||||
```js
|
||||
/* load SheetJS Library */
|
||||
const XLSX = require("xlsx");
|
||||
/* load fastify and enable body parsing */
|
||||
const fastify = require('fastify')({logger: true});
|
||||
fastify.register(require('@fastify/multipart'), { attachFieldsToBody: true });
|
||||
|
||||
/* GET / returns a workbook */
|
||||
fastify.get('/', (req, reply) => {
|
||||
/* make a workbook */
|
||||
var wb = XLSX.read("S,h,e,e,t,J,S\n5,4,3,3,7,9,5", {type: "binary"});
|
||||
|
||||
/* write to Buffer */
|
||||
const buf = XLSX.write(wb, {type:"buffer", bookType: "xlsx"});
|
||||
|
||||
/* set Content-Disposition header and send data */
|
||||
reply.header('Content-Disposition', 'attachment; filename="SheetJSFastify.xlsx"').send(buf);
|
||||
});
|
||||
|
||||
/* POST / reads submitted file and exports to requested format */
|
||||
fastify.post('/', async(req, reply) => {
|
||||
|
||||
/* "file" is the name of the field in the HTML form*/
|
||||
const file = req.body.upload;
|
||||
|
||||
/* toBuffer returns a promise that resolves to a Buffer */
|
||||
const wb = XLSX.read(await file.toBuffer());
|
||||
|
||||
/* send back a CSV */
|
||||
reply.send(XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]]));
|
||||
});
|
||||
|
||||
/* start */
|
||||
fastify.listen({port: process.env.PORT || 3000}, (err, addr) => { if(err) throw err; });
|
||||
```
|
||||
|
||||
1) Install dependencies:
|
||||
|
||||
```bash
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz fastify @fastify/multipart
|
||||
```
|
||||
|
||||
2) Start server
|
||||
|
||||
```bash
|
||||
node SheetJSFastify.js
|
||||
```
|
||||
|
||||
3) Test POST requests using <https://sheetjs.com/pres.numbers>:
|
||||
|
||||
```bash
|
||||
curl -LO https://sheetjs.com/pres.numbers
|
||||
curl -X POST -F upload=@pres.numbers http://localhost:3000/
|
||||
```
|
||||
|
||||
The response should show the data in CSV rows.
|
||||
|
||||
4) Test GET requests by opening http://localhost:3000/ in your browser.
|
||||
|
||||
It should prompt to download `SheetJSFastify.xlsx`
|
||||
|
||||
</details>
|
||||
|
@ -1,4 +1,5 @@
|
||||
---
|
||||
pagination_prev: getting-started/index
|
||||
sidebar_position: 1
|
||||
hide_table_of_contents: true
|
||||
---
|
||||
@ -19,7 +20,7 @@ The demo projects include small runnable examples and short explainers.
|
||||
|
||||
### Frameworks
|
||||
|
||||
- [`Angular 2+ and Ionic`](./angular)
|
||||
- [`Angular`](./angular)
|
||||
- [`React`](./react)
|
||||
- [`VueJS`](./vue)
|
||||
- [`Angular.JS`](./legacy#angularjs)
|
||||
|
@ -8,9 +8,57 @@ The ["Common Spreadsheet Format"](../csf/general) is a simple object
|
||||
representation of the core concepts of a workbook. The utility functions work
|
||||
with the object representation and are intended to handle common use cases.
|
||||
|
||||
## Modifying Workbook Structure
|
||||
The [Data Input](./input) and [Data Output](./output) sections cover how to
|
||||
read from data sources and write to data sources.
|
||||
|
||||
#### API
|
||||
## Workbook
|
||||
|
||||
### Worksheets
|
||||
|
||||
:::note
|
||||
|
||||
Worksheet names are case-sensitive.
|
||||
|
||||
:::
|
||||
|
||||
_List the Worksheet names in tab order_
|
||||
|
||||
```js
|
||||
var wsnames = workbook.SheetNames;
|
||||
```
|
||||
|
||||
The `SheetNames` property of the workbook object is a list of the worksheet
|
||||
names in "tab order". API functions will look at this array.
|
||||
|
||||
_Access a Worksheet by name_
|
||||
|
||||
```js
|
||||
var worksheet = workbook.Sheets[sheet_name];
|
||||
```
|
||||
|
||||
The workbook object's `Sheets` property is an object whose keys are sheet names
|
||||
and whose values are worksheet objects.
|
||||
|
||||
_Access the first Worksheet_
|
||||
|
||||
```js
|
||||
var first_ws = workbook.Sheets[workbook.SheetNames[0]];
|
||||
```
|
||||
|
||||
Combining the previous examples, `workbook.Sheets[workbook.SheetNames[n]]` is
|
||||
the `n`-th worksheet if it exists in the workbook.
|
||||
|
||||
|
||||
_Replace a Worksheet in place_
|
||||
|
||||
```js
|
||||
workbook.Sheets[sheet_name] = new_worksheet;
|
||||
```
|
||||
|
||||
The `Sheets` property of the workbook object is an object whose keys are names
|
||||
and whose values are worksheet objects. By reassigning to a property of the
|
||||
`Sheets` object, the worksheet object can be changed without disrupting the
|
||||
rest of the worksheet structure.
|
||||
|
||||
_Append a Worksheet to a Workbook_
|
||||
|
||||
@ -40,30 +88,8 @@ XLSX.utils.book_append_sheet(workbook, sheetC, "Sheet2", true); // Sheet4
|
||||
XLSX.utils.book_append_sheet(workbook, sheetD, "Sheet2", true); // Sheet5
|
||||
```
|
||||
|
||||
_List the Worksheet names in tab order_
|
||||
|
||||
```js
|
||||
var wsnames = workbook.SheetNames;
|
||||
```
|
||||
|
||||
The `SheetNames` property of the workbook object is a list of the worksheet
|
||||
names in "tab order". API functions will look at this array.
|
||||
|
||||
_Replace a Worksheet in place_
|
||||
|
||||
```js
|
||||
workbook.Sheets[sheet_name] = new_worksheet;
|
||||
```
|
||||
|
||||
The `Sheets` property of the workbook object is an object whose keys are names
|
||||
and whose values are worksheet objects. By reassigning to a property of the
|
||||
`Sheets` object, the worksheet object can be changed without disrupting the
|
||||
rest of the worksheet structure.
|
||||
|
||||
#### Examples
|
||||
|
||||
This example uses [`XLSX.utils.aoa_to_sheet`](../api/utilities#array-of-arrays-input).
|
||||
|
||||
```js
|
||||
var ws_name = "SheetJS";
|
||||
|
||||
@ -74,21 +100,53 @@ var ws_data = [
|
||||
];
|
||||
var ws = XLSX.utils.aoa_to_sheet(ws_data);
|
||||
|
||||
/* Create workbook */
|
||||
var wb = XLSX.utils.book_new();
|
||||
|
||||
/* Add the worksheet to the workbook */
|
||||
// highlight-next-line
|
||||
XLSX.utils.book_append_sheet(wb, ws, ws_name);
|
||||
|
||||
/* Write to file */
|
||||
XLSX.writeFile(wb, "SheetJS.xlsx");
|
||||
```
|
||||
|
||||
## Modifying Cell Values
|
||||
### Other Properties
|
||||
|
||||
#### API
|
||||
_Add a Defined Name_
|
||||
|
||||
_Modify a single cell value in a worksheet_
|
||||
```js
|
||||
if(!workbook.Workbook) workbook.Workbook = {};
|
||||
if(!workbook.Workbook.Names) workbook.Workbook.Names = [];
|
||||
workbook.Workbook.Names.push({
|
||||
Name: "SourceData",
|
||||
Ref: "Sheet1!A1:D12"
|
||||
});
|
||||
```
|
||||
|
||||
This is described in more detail in ["Workbook Object"](../csf/book#defined-names).
|
||||
|
||||
_Set Workbook Properties_
|
||||
|
||||
```js
|
||||
if(!wb.Props) wb.Props = {};
|
||||
wb.Props["Company"] = "SheetJS LLC";
|
||||
```
|
||||
|
||||
The full set of property names, and their mapping to the Excel UI, is included
|
||||
in ["File Properties"](../csf/book#file-properties)
|
||||
|
||||
## Worksheet
|
||||
|
||||
### Cells
|
||||
|
||||
_Modify a single cell value in a Worksheet_
|
||||
|
||||
```js
|
||||
XLSX.utils.sheet_add_aoa(worksheet, [[new_value]], { origin: address });
|
||||
```
|
||||
|
||||
_Modify multiple cell values in a worksheet_
|
||||
_Modify multiple cell values in a Worksheet_
|
||||
|
||||
```js
|
||||
XLSX.utils.sheet_add_aoa(worksheet, aoa, opts);
|
||||
@ -122,8 +180,29 @@ XLSX.utils.sheet_add_aoa(worksheet, [
|
||||
], { origin: -1 });
|
||||
```
|
||||
|
||||
## Modifying Other Worksheet / Workbook / Cell Properties
|
||||
### Other Properties
|
||||
|
||||
The ["Common Spreadsheet Format"](../csf/general) section describes
|
||||
the object structures in greater detail.
|
||||
_Merge a group of cells_
|
||||
|
||||
```js
|
||||
if(!worksheet["!merges"]) worksheet["!merges"] = [];
|
||||
worksheet["!merges"].push(XLSX.utils.decode_range("A1:E1"));
|
||||
```
|
||||
|
||||
The `!merges` property of a worksheet object is a list of [Cell Ranges](../csf/general#cell-ranges).
|
||||
The data for the cell will be taken from the top-left cell.
|
||||
|
||||
A range can be created with `decode_range` or specified manually:
|
||||
|
||||
```js
|
||||
worksheet["!merges"].push({
|
||||
s: { r: 2, c: 1 }, // s ("start"): c = 1 r = 2 -> "B3"
|
||||
e: { r: 3, c: 4 } // e ("end"): c = 4 r = 3 -> "E4"
|
||||
});
|
||||
```
|
||||
|
||||
:::caution
|
||||
|
||||
This approach does not verify if two merged ranges intersect.
|
||||
|
||||
:::
|
||||
|
@ -1,4 +1,5 @@
|
||||
---
|
||||
pagination_next: api/index
|
||||
hide_table_of_contents: true
|
||||
title: Common Spreadsheet Format
|
||||
---
|
||||
|
@ -1,4 +1,5 @@
|
||||
---
|
||||
pagination_prev: csf/index
|
||||
sidebar_position: 5
|
||||
title: API Reference
|
||||
---
|
||||
|
Loading…
Reference in New Issue
Block a user