forked from sheetjs/docs.sheetjs.com
		
	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