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