forked from sheetjs/docs.sheetjs.com
		
	webapi
This commit is contained in:
		
							parent
							
								
									ceca03b7e1
								
							
						
					
					
						commit
						5499547bf9
					
				
							
								
								
									
										203
									
								
								.spelling
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										203
									
								
								.spelling
									
									
									
									
									
								
							@ -1,83 +1,88 @@
 | 
			
		||||
# xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com
 | 
			
		||||
SheetJS
 | 
			
		||||
sheetjs
 | 
			
		||||
js-xlsx
 | 
			
		||||
xls
 | 
			
		||||
xlsb
 | 
			
		||||
xlsx
 | 
			
		||||
docs.sheetjs.com
 | 
			
		||||
 | 
			
		||||
# Doc Structure
 | 
			
		||||
TabItem
 | 
			
		||||
DocCardList
 | 
			
		||||
 | 
			
		||||
# Excel-related terms
 | 
			
		||||
A1-style
 | 
			
		||||
A1-Style
 | 
			
		||||
AutoFilter
 | 
			
		||||
BIFF2
 | 
			
		||||
BIFF3
 | 
			
		||||
BIFF4
 | 
			
		||||
BIFF5
 | 
			
		||||
BIFF8
 | 
			
		||||
BIFF12
 | 
			
		||||
CFB
 | 
			
		||||
CSV
 | 
			
		||||
Chartsheet
 | 
			
		||||
Chartsheets
 | 
			
		||||
DBF
 | 
			
		||||
DIF
 | 
			
		||||
Dialogsheet
 | 
			
		||||
Dialogsheets
 | 
			
		||||
ECMA-376
 | 
			
		||||
FODS
 | 
			
		||||
FoxPro
 | 
			
		||||
IEEE754
 | 
			
		||||
JSON
 | 
			
		||||
Macrosheet
 | 
			
		||||
Macrosheets
 | 
			
		||||
Multiplan
 | 
			
		||||
ODF
 | 
			
		||||
ODS
 | 
			
		||||
OData
 | 
			
		||||
OpenDocument
 | 
			
		||||
OpenFormula
 | 
			
		||||
PRN
 | 
			
		||||
PivotTable
 | 
			
		||||
PivotTables
 | 
			
		||||
QPW
 | 
			
		||||
Quattro
 | 
			
		||||
RFC4180
 | 
			
		||||
RTF
 | 
			
		||||
SLK
 | 
			
		||||
SYLK
 | 
			
		||||
SpreadsheetML
 | 
			
		||||
TSV
 | 
			
		||||
TXT
 | 
			
		||||
UOS1
 | 
			
		||||
UOS2
 | 
			
		||||
Unhide
 | 
			
		||||
VBA
 | 
			
		||||
Visicalc
 | 
			
		||||
Chartsheet
 | 
			
		||||
WB1
 | 
			
		||||
WB2
 | 
			
		||||
WB3
 | 
			
		||||
WK1
 | 
			
		||||
WK2
 | 
			
		||||
WK3
 | 
			
		||||
WK4
 | 
			
		||||
WKS
 | 
			
		||||
WK_
 | 
			
		||||
WQ1
 | 
			
		||||
WQ2
 | 
			
		||||
WQ3
 | 
			
		||||
XLML
 | 
			
		||||
XLR
 | 
			
		||||
XLS
 | 
			
		||||
XLW
 | 
			
		||||
XLSB
 | 
			
		||||
XLSM
 | 
			
		||||
XLSX
 | 
			
		||||
chartsheet
 | 
			
		||||
Chartsheets
 | 
			
		||||
chartsheets
 | 
			
		||||
Dialogsheet
 | 
			
		||||
dialogsheet
 | 
			
		||||
Dialogsheets
 | 
			
		||||
dialogsheets
 | 
			
		||||
dBASE
 | 
			
		||||
Macrosheet
 | 
			
		||||
dialogsheet
 | 
			
		||||
dialogsheets
 | 
			
		||||
macrosheet
 | 
			
		||||
Macrosheets
 | 
			
		||||
macrosheets
 | 
			
		||||
tooltip
 | 
			
		||||
tooltips
 | 
			
		||||
 | 
			
		||||
# Third-party
 | 
			
		||||
Browserify
 | 
			
		||||
CDNjs
 | 
			
		||||
CommonJS
 | 
			
		||||
Deno
 | 
			
		||||
Ethercalc
 | 
			
		||||
ExtendScript
 | 
			
		||||
InDesign
 | 
			
		||||
IndexedDB
 | 
			
		||||
JavaScriptCore
 | 
			
		||||
LocalStorage
 | 
			
		||||
MacOS
 | 
			
		||||
NestJS
 | 
			
		||||
NetSuite
 | 
			
		||||
NPM
 | 
			
		||||
Nuxt
 | 
			
		||||
PhantomJS
 | 
			
		||||
Photoshop
 | 
			
		||||
ReactJS
 | 
			
		||||
Redis
 | 
			
		||||
RequireJS
 | 
			
		||||
Rollup
 | 
			
		||||
SessionStorage
 | 
			
		||||
SQLite
 | 
			
		||||
SuiteScripts
 | 
			
		||||
SystemJS
 | 
			
		||||
VueJS
 | 
			
		||||
WebKit
 | 
			
		||||
WebSQL
 | 
			
		||||
WK_
 | 
			
		||||
axios
 | 
			
		||||
iOS
 | 
			
		||||
iWork
 | 
			
		||||
nodejs
 | 
			
		||||
node.js
 | 
			
		||||
npm
 | 
			
		||||
unpkg
 | 
			
		||||
webpack
 | 
			
		||||
weex
 | 
			
		||||
标文通
 | 
			
		||||
 | 
			
		||||
# Other terms
 | 
			
		||||
1.x
 | 
			
		||||
@ -89,38 +94,109 @@ weex
 | 
			
		||||
7.x
 | 
			
		||||
8.x
 | 
			
		||||
9.x
 | 
			
		||||
ActiveX
 | 
			
		||||
APIs
 | 
			
		||||
ActiveX
 | 
			
		||||
ArrayBuffer
 | 
			
		||||
Base64
 | 
			
		||||
Booleans
 | 
			
		||||
Browserify
 | 
			
		||||
Bundlers
 | 
			
		||||
CMS
 | 
			
		||||
CS6
 | 
			
		||||
CapacitorJS
 | 
			
		||||
CommonJS
 | 
			
		||||
Cordova
 | 
			
		||||
Deno
 | 
			
		||||
Drash
 | 
			
		||||
Ethercalc
 | 
			
		||||
ExtendScript
 | 
			
		||||
FileReader
 | 
			
		||||
GatsbyJS
 | 
			
		||||
HTML
 | 
			
		||||
HTML5
 | 
			
		||||
IE
 | 
			
		||||
IE10
 | 
			
		||||
IE11
 | 
			
		||||
IE6
 | 
			
		||||
IE9
 | 
			
		||||
InDesign
 | 
			
		||||
IndexedDB
 | 
			
		||||
JS
 | 
			
		||||
JSX
 | 
			
		||||
JavaScriptCore
 | 
			
		||||
LLC
 | 
			
		||||
LocalStorage
 | 
			
		||||
Lume
 | 
			
		||||
MacOS
 | 
			
		||||
NPM
 | 
			
		||||
NestJS
 | 
			
		||||
NetSuite
 | 
			
		||||
NextJS
 | 
			
		||||
NoSQL
 | 
			
		||||
NodeJS
 | 
			
		||||
Nunjucks
 | 
			
		||||
Nuxt
 | 
			
		||||
NuxtJS
 | 
			
		||||
PhantomJS
 | 
			
		||||
Photoshop
 | 
			
		||||
README
 | 
			
		||||
UTF-8
 | 
			
		||||
RESTlets
 | 
			
		||||
ReactJS
 | 
			
		||||
Redis
 | 
			
		||||
RequireJS
 | 
			
		||||
Rollup
 | 
			
		||||
SQLite
 | 
			
		||||
SWC
 | 
			
		||||
SessionStorage
 | 
			
		||||
Snowpack
 | 
			
		||||
SuiteScript
 | 
			
		||||
SuiteScripts
 | 
			
		||||
Suitelets
 | 
			
		||||
SystemJS
 | 
			
		||||
Tauri
 | 
			
		||||
UI
 | 
			
		||||
UI5
 | 
			
		||||
URI
 | 
			
		||||
UTF-16
 | 
			
		||||
UTF-8
 | 
			
		||||
VBScript
 | 
			
		||||
ViteJS
 | 
			
		||||
VueJS
 | 
			
		||||
WMR
 | 
			
		||||
WSL
 | 
			
		||||
WebKit
 | 
			
		||||
WebSQL
 | 
			
		||||
Webpack
 | 
			
		||||
XHR
 | 
			
		||||
XMLHttpRequest
 | 
			
		||||
async
 | 
			
		||||
axios
 | 
			
		||||
bundler
 | 
			
		||||
bundlers
 | 
			
		||||
cleanroom
 | 
			
		||||
codepage
 | 
			
		||||
commonjs
 | 
			
		||||
config
 | 
			
		||||
customizable
 | 
			
		||||
datagrid
 | 
			
		||||
dataset
 | 
			
		||||
deduplication
 | 
			
		||||
destructuring
 | 
			
		||||
disambiguate
 | 
			
		||||
embeddable
 | 
			
		||||
encodings
 | 
			
		||||
filesystem
 | 
			
		||||
globals
 | 
			
		||||
iOS
 | 
			
		||||
iWork
 | 
			
		||||
javascript
 | 
			
		||||
lifecycle
 | 
			
		||||
metadata
 | 
			
		||||
natively
 | 
			
		||||
node.js
 | 
			
		||||
nodejs
 | 
			
		||||
npm
 | 
			
		||||
parsers
 | 
			
		||||
pre-built
 | 
			
		||||
pre-generated
 | 
			
		||||
prepend
 | 
			
		||||
@ -129,13 +205,15 @@ programmatically
 | 
			
		||||
repo
 | 
			
		||||
runtime
 | 
			
		||||
serverless
 | 
			
		||||
subfolder
 | 
			
		||||
submodule
 | 
			
		||||
transpiled
 | 
			
		||||
utils
 | 
			
		||||
commonjs
 | 
			
		||||
async
 | 
			
		||||
uncheck
 | 
			
		||||
unpkg
 | 
			
		||||
utils
 | 
			
		||||
vendoring
 | 
			
		||||
webpack
 | 
			
		||||
weex
 | 
			
		||||
 | 
			
		||||
 - demos/altjs/README.md
 | 
			
		||||
ChakraCore
 | 
			
		||||
@ -198,11 +276,4 @@ vscode-data-preview
 | 
			
		||||
axios
 | 
			
		||||
superagent
 | 
			
		||||
 | 
			
		||||
LLC
 | 
			
		||||
Bundlers
 | 
			
		||||
JSON
 | 
			
		||||
QPW
 | 
			
		||||
XLML
 | 
			
		||||
XLS
 | 
			
		||||
XLSB
 | 
			
		||||
XLSX
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							@ -12,7 +12,7 @@ serve:
 | 
			
		||||
 | 
			
		||||
.PHONY: spell
 | 
			
		||||
spell:
 | 
			
		||||
	npx spellchecker-cli -d .spelling -f 'docz/**/*.md*'
 | 
			
		||||
	npx spellchecker-cli -d .spelling -f 'docz/**/*.md*' --no-suggestions
 | 
			
		||||
 | 
			
		||||
.PHONY: index
 | 
			
		||||
index: readme ## Rebuild site
 | 
			
		||||
 | 
			
		||||
@ -79,8 +79,8 @@ For general stability, "vendoring" modules is the recommended approach:
 | 
			
		||||
<div>1) Download the tarball (<code parentName="pre">xlsx-{current}.tgz</code>) for the desired version. The current
 | 
			
		||||
   version is available at <a href={`https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}>https://cdn.sheetjs.com/xlsx-{current}/xlsx-{current}.tgz</a></div><br/>
 | 
			
		||||
 | 
			
		||||
2) Create a `vendor` subdirectory at the root of your project and move the
 | 
			
		||||
   tarball to that folder.  Add it to your project repository.
 | 
			
		||||
2) Create a `vendor` subfolder at the root of your project and move the tarball
 | 
			
		||||
   to that folder.  Add it to your project repository.
 | 
			
		||||
 | 
			
		||||
3) Install the tarball using a package manager:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -58,7 +58,7 @@ const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")
 | 
			
		||||
### Reshaping the Array
 | 
			
		||||
 | 
			
		||||
For this example, the name will be the first name combined with the last name
 | 
			
		||||
(`row.name.first + " " + row.name.last`) and the birthday will be the subfield
 | 
			
		||||
(`row.name.first + " " + row.name.last`) and the birthday will be available at
 | 
			
		||||
`row.bio.birthday`.  Using `Array#map`, the dataset can be massaged in one call:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
@ -109,8 +109,8 @@ additional styling options like cell styling and frozen rows.
 | 
			
		||||
By default, `json_to_sheet` creates a worksheet with a header row. In this case,
 | 
			
		||||
the headers come from the JS object keys: "name" and "birthday".
 | 
			
		||||
 | 
			
		||||
The headers are in cells A1 and B1.  `XLSX.utils.sheet_add_aoa` can write text
 | 
			
		||||
values to the existing worksheet starting at cell A1:
 | 
			
		||||
The headers are in cells `A1` and `B1`.  `XLSX.utils.sheet_add_aoa` can write
 | 
			
		||||
text values to the existing worksheet starting at cell `A1`:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
 | 
			
		||||
 | 
			
		||||
@ -170,7 +170,7 @@ To run the example, save the following script to `SheetJSPhantom.js` in the same
 | 
			
		||||
folder as `phantomjs.exe` or `phantomjs` and run
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
./phantomjs SheetJSPhantom.js     ## macOS / Linux
 | 
			
		||||
./phantomjs SheetJSPhantom.js     ## MacOS / Linux
 | 
			
		||||
.\phantomjs.exe SheetJSPhantom.js ## windows
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -965,7 +965,7 @@ As it uses `fetch`, this demo requires Node 18.
 | 
			
		||||
 | 
			
		||||
ViteJS adopted nascent `package.json` patterns. Version 0.18.10 implements the
 | 
			
		||||
patterns required for ViteJS 3.0.3. These patterns are evolving and a future
 | 
			
		||||
version of Vite may require more packaging changes.
 | 
			
		||||
version of ViteJS may require more packaging changes.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -73,7 +73,7 @@ files and convert to CSV.
 | 
			
		||||
 | 
			
		||||
Older versions of IE do not support HTML5 File API but do support Base64.
 | 
			
		||||
 | 
			
		||||
On OSX you can get the Base64 encoding with:
 | 
			
		||||
On MacOS you can get the Base64 encoding with:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
$ <target_file base64 | pbcopy
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@ sidebar_position: 17
 | 
			
		||||
# Clipboard Data
 | 
			
		||||
 | 
			
		||||
Spreadsheet software like Excel typically support copying and pasting cells and
 | 
			
		||||
data. This is implemented through the Clipboard ("Pasteboard" in OSX parlance).
 | 
			
		||||
data. This is implemented through the Clipboard ("Pasteboard" in MacOS).
 | 
			
		||||
 | 
			
		||||
When copying a selection of cells, Excel for Windows stores a screenshot of the
 | 
			
		||||
selected cells as an image.  It also creates and stores a number of strings and
 | 
			
		||||
@ -159,7 +159,7 @@ Electron additionally supports binary operations using `Buffer` objects.  This
 | 
			
		||||
support is considered "experimental" and is not guaranteed to work on any
 | 
			
		||||
platform.  Issues should be raised with the Electron project
 | 
			
		||||
 | 
			
		||||
On the `macOS` platform, some versions of Excel store a packaged file with key
 | 
			
		||||
On the `MacOS` platform, some versions of Excel store a packaged file with key
 | 
			
		||||
`dyn.ah62d4qmxhk4d425try1g44pdsm11g55gsu1en5pcqzwc4y5tsz3gg3k`.  The package is
 | 
			
		||||
a simple CFB file that can be parsed:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -81,7 +81,7 @@ duk_pop(ctx);
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
 | 
			
		||||
This demo was tested on macOS x64.
 | 
			
		||||
This demo was tested on MacOS x64.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
@ -444,15 +444,15 @@ hermes xlsx.hermes.js
 | 
			
		||||
 | 
			
		||||
:::warning Platform Limitations
 | 
			
		||||
 | 
			
		||||
JavaScriptCore is primarily deployed in macOS and iOS applications.  There is
 | 
			
		||||
JavaScriptCore is primarily deployed in MacOS and iOS applications.  There is
 | 
			
		||||
some experimental support through the Bun runtime, but production applications
 | 
			
		||||
intending to support Windows / Linux / Android should try to embed V8.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
iOS and OSX ship with the JavaScriptCore framework for running JS scripts from
 | 
			
		||||
iOS and MacOS ship with the JavaScriptCore framework for running JS code from
 | 
			
		||||
Swift and Objective-C.  Hybrid function invocation is tricky, but explicit data
 | 
			
		||||
passing is straightforward.  The demo shows a standalone Swift example for OSX.
 | 
			
		||||
passing is straightforward. The demo shows a standalone Swift sample for MacOS.
 | 
			
		||||
 | 
			
		||||
Binary strings can be passed back and forth using `String.Encoding.isoLatin1`.
 | 
			
		||||
 | 
			
		||||
@ -502,9 +502,9 @@ The demo includes a sample `SheetJSCore` Wrapper class to simplify operations.
 | 
			
		||||
 | 
			
		||||
<details><summary><b>Complete Example</b> (click to show)</summary>
 | 
			
		||||
 | 
			
		||||
:::caution This demo only runs on macOS
 | 
			
		||||
:::caution This demo only runs on MacOS
 | 
			
		||||
 | 
			
		||||
This example requires macOS + Swift and will not work on Windows or Linux!
 | 
			
		||||
This example requires MacOS + Swift and will not work on Windows or Linux!
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ The ["JavaScript Engines"](./engines) section includes samples for JavaScript
 | 
			
		||||
engines used in the mobile app frameworks.  SheetJS libraries have been tested
 | 
			
		||||
in the relevant engines and should "just work" with some caveats.
 | 
			
		||||
 | 
			
		||||
:::caution readFile and writeFile
 | 
			
		||||
:::caution `readFile` and `writeFile`
 | 
			
		||||
 | 
			
		||||
`XLSX.readFile` and `XLSX.writeFile` do not work in mobile apps!  The demos
 | 
			
		||||
include platform-specific details for fetching file data for `XLSX.read` and
 | 
			
		||||
@ -39,7 +39,7 @@ provide, usually there are third-party modules to provide needed functionality.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
macOS is required for the iOS demos.  The Android demos were tested on macOS.
 | 
			
		||||
MacOS is required for the iOS demos.  The Android demos were tested on MacOS.
 | 
			
		||||
 | 
			
		||||
## React Native
 | 
			
		||||
 | 
			
		||||
@ -605,7 +605,7 @@ The app can be tested with the following sequence in the simulator:
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
- Make sure "On My iPhone" is highlighted and select "Save"
 | 
			
		||||
- Click the Home icon again then select the SheetJSRN app
 | 
			
		||||
- Click the Home icon again then select the `SheetJSRN` app
 | 
			
		||||
- Click "Import data" and select `pres`:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
@ -735,7 +735,7 @@ with Angular and TypeScript is assumed.
 | 
			
		||||
 | 
			
		||||
<details><summary><b>Complete Example</b> (click to show)</summary>
 | 
			
		||||
 | 
			
		||||
0) Follow the official Environment Setup instructions (tested with "macOS + iOS")
 | 
			
		||||
0) Follow the official Environment Setup instructions (tested with "MacOS + iOS")
 | 
			
		||||
 | 
			
		||||
1) Create a skeleton NativeScript + Angular app:
 | 
			
		||||
 | 
			
		||||
@ -1011,7 +1011,7 @@ The iOS simulator runs iOS 15.5 on an iPhone SE 3rd generation.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
This demo will focus on VueJS and Cordova with the Quasar Vite starter project.
 | 
			
		||||
This demo will use the Quasar ViteJS starter project with VueJS and Cordova.
 | 
			
		||||
 | 
			
		||||
### Integration Details
 | 
			
		||||
 | 
			
		||||
@ -1274,7 +1274,7 @@ To test that reading works:
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
- Make sure "On My iPhone" is highlighted and select "Save"
 | 
			
		||||
- Click the Home icon again then select the SheetJSQuasar app
 | 
			
		||||
- Click the Home icon again then select the `SheetJSQuasar` app
 | 
			
		||||
- Click the "Load" button, then select "Choose File" and select `pres`:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
@ -1381,7 +1381,7 @@ The iOS simulator runs iOS 15.5 on an iPod Touch 7th Gen.
 | 
			
		||||
 | 
			
		||||
:::warning Telemetry
 | 
			
		||||
 | 
			
		||||
Before starting this demo, manually disable telemetry.  On Linux and macOS:
 | 
			
		||||
Before starting this demo, manually disable telemetry.  On Linux and MacOS:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
rm -rf ~/.ionic/
 | 
			
		||||
 | 
			
		||||
@ -29,7 +29,7 @@ This was tested against `next v12.2.5` on 2022 August 16.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
:::caution
 | 
			
		||||
:::info
 | 
			
		||||
 | 
			
		||||
At a high level, there are two ways to pull spreadsheet data into NextJS apps:
 | 
			
		||||
loading an asset module or performing the file read operations from the NextJS
 | 
			
		||||
@ -145,7 +145,7 @@ export async function getStaticProps(ctx) {
 | 
			
		||||
 | 
			
		||||
These routes require a NodeJS dynamic server. Static page generation will fail!
 | 
			
		||||
 | 
			
		||||
`getStaticProps` and `getStaticPaths` support SSG.
 | 
			
		||||
`getStaticProps` and `getStaticPaths` support static site generation (SSG).
 | 
			
		||||
 | 
			
		||||
`getServerSideProps` is suited for NodeJS hosted deployments where the workbook
 | 
			
		||||
changes frequently and a static site is undesirable.
 | 
			
		||||
@ -185,14 +185,14 @@ npx next telemetry status
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
1) Set up folder structure.  At the end, a `pages` folder with a `sheets`
 | 
			
		||||
   subfolder must be created.  On Linux or macOS or WSL:
 | 
			
		||||
   subfolder must be created.  On Linux or MacOS or WSL:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
mkdir -p pages/sheets/
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
2) Download the [test file](pathname:///next/sheetjs.xlsx) and place in the
 | 
			
		||||
   project root.  On Linux or macOS or WSL:
 | 
			
		||||
   project root.  On Linux or MacOS or WSL:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
curl -LO https://docs.sheetjs.com/next/sheetjs.xlsx
 | 
			
		||||
@ -206,7 +206,7 @@ npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz next
 | 
			
		||||
 | 
			
		||||
4) Download test scripts:
 | 
			
		||||
 | 
			
		||||
Download and place the following scripts in the `pages` subdirectory:
 | 
			
		||||
Download and place the following scripts in the `pages` subfolder:
 | 
			
		||||
 | 
			
		||||
- [`index.js`](pathname:///next/index.js)
 | 
			
		||||
- [`getServerSideProps.js`](pathname:///next/getServerSideProps.js)
 | 
			
		||||
@ -214,7 +214,7 @@ Download and place the following scripts in the `pages` subdirectory:
 | 
			
		||||
- [`getStaticProps.js`](pathname:///next/getStaticProps.js)
 | 
			
		||||
 | 
			
		||||
Download [`[id].js`](pathname:///next/%5Bid%5D.js) and place in the
 | 
			
		||||
`pages/sheets` subdirectory.
 | 
			
		||||
`pages/sheets` subfolder.
 | 
			
		||||
 | 
			
		||||
:::caution Percent-Encoding in the script name
 | 
			
		||||
 | 
			
		||||
@ -223,7 +223,7 @@ browser saved the file to `%5Bid%5D.js`. rename the file.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
On Linux or macOS or WSL:
 | 
			
		||||
On Linux or MacOS or WSL:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
cd pages
 | 
			
		||||
@ -255,7 +255,7 @@ The individual worksheets are available at
 | 
			
		||||
- http://localhost:3000/sheets/1
 | 
			
		||||
- http://localhost:3000/sheets/2
 | 
			
		||||
 | 
			
		||||
6) Stop the dev server and run a production build:
 | 
			
		||||
6) Stop the server and run a production build:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
npx next build
 | 
			
		||||
@ -315,13 +315,13 @@ Route (pages)                              Size     First Load JS
 | 
			
		||||
npx next export
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The static site will be written to the `out` subdirectory, which can be hosted with
 | 
			
		||||
The static site will be written to the `out` subfolder, which can be hosted with
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
npx http-server out
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The command will start a local webserver on port 8080.
 | 
			
		||||
The command will start a local HTTP server on port 8080.
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
@ -419,7 +419,7 @@ npx create-nuxt-app SheetJSNuxt
 | 
			
		||||
 | 
			
		||||
When prompted, enter the following options:
 | 
			
		||||
 | 
			
		||||
- `Project name`: press Enter (use default SheetJSNuxt)
 | 
			
		||||
- `Project name`: press Enter (use default `SheetJSNuxt`)
 | 
			
		||||
- `Programming language`: press Down Arrow (`TypeScript` selected) then Enter
 | 
			
		||||
- `Package manager`: select `Npm` and press Enter
 | 
			
		||||
- `UI framework`: select `None` and press Enter
 | 
			
		||||
@ -434,7 +434,7 @@ When prompted, enter the following options:
 | 
			
		||||
 | 
			
		||||
The project will be configured and modules will be installed.
 | 
			
		||||
 | 
			
		||||
2) Install the SheetJS library and start the dev server:
 | 
			
		||||
2) Install the SheetJS library and start the server:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
cd SheetJSNuxt
 | 
			
		||||
@ -445,11 +445,10 @@ npm run dev
 | 
			
		||||
When the build finishes, the terminal will display a URL like:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
ℹ Listening on: http://localhost:64688/                                                            05:41:11
 | 
			
		||||
No issues found.                                                                                   05:41:11
 | 
			
		||||
ℹ Listening on: http://localhost:64688/
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The dev server is listening on that URL.  Open the link in a web browser.
 | 
			
		||||
The server is listening on that URL.  Open the link in a web browser.
 | 
			
		||||
 | 
			
		||||
3) Download <https://sheetjs.com/pres.xlsx> and move to the `content` folder.
 | 
			
		||||
 | 
			
		||||
@ -492,7 +491,7 @@ in Excel.  Add a new row to the bottom and save the file:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
The dev server terminal should show a line like:
 | 
			
		||||
The server terminal window should show a line like:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
ℹ Updated ./content/pres.xlsx                                       @nuxt/content 05:43:37
 | 
			
		||||
@ -502,7 +501,7 @@ The page should automatically refresh with the new content:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
7) Stop the dev server (press `CTRL+C` in the terminal window) and run
 | 
			
		||||
7) Stop the server (press `CTRL+C` in the terminal window) and run
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
npm run generate
 | 
			
		||||
@ -519,3 +518,52 @@ the static nature is trivial: make another change in Excel and save.  The page
 | 
			
		||||
will not change.
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
## Lume
 | 
			
		||||
 | 
			
		||||
Lume is a static site generator for the Deno platform.
 | 
			
		||||
 | 
			
		||||
`lume#loadData` can add custom loaders for data.  The loader method receives a
 | 
			
		||||
path to the file, which can be read with `XLSX.readFile`.  This should be added
 | 
			
		||||
to `_config.js`, like in the example below:
 | 
			
		||||
 | 
			
		||||
```js title="_config.js"
 | 
			
		||||
import lume from "lume/mod.ts";
 | 
			
		||||
import { readFile, utils } from 'https://cdn.sheetjs.com/xlsx-latest/package/xlsx.mjs';
 | 
			
		||||
 | 
			
		||||
function wbLoader(path) {
 | 
			
		||||
  const wb = readFile(path);
 | 
			
		||||
  const res = wb.SheetNames.map(n => ({
 | 
			
		||||
    name: n,
 | 
			
		||||
    data: utils.sheet_to_json(wb.Sheets[n])
 | 
			
		||||
  }));
 | 
			
		||||
  return { data: res };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const site = lume();
 | 
			
		||||
const exts = [".xlsx", ".numbers", /* ... other supported extensions */];
 | 
			
		||||
// highlight-next-line
 | 
			
		||||
site.loadData(exts, wbLoader);
 | 
			
		||||
 | 
			
		||||
export default site;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The actual spreadsheets should be placed in the `_data` subfolder.
 | 
			
		||||
 | 
			
		||||
The variable name is the stem of the filename (`sheetjs` if `sheetjs.xlsx` or
 | 
			
		||||
`sheetjs.numbers` exists).  A Nunjucks or JSX template can loop through the
 | 
			
		||||
worksheets and the data rows. The example assumes each worksheet has a `name` and `index` column:
 | 
			
		||||
 | 
			
		||||
```jsx title="index.jsx"
 | 
			
		||||
export default ({sheetjs}) => {
 | 
			
		||||
  return (<>{(sheetjs.data).map(sheet => (<>
 | 
			
		||||
    <h2>{sheet.name}</h2>
 | 
			
		||||
    <table><thead><th>Name</th><th>Index</th></thead>
 | 
			
		||||
    <tbody>{sheet.data.map(row => (<tr>
 | 
			
		||||
      <td>{row.name}</td>
 | 
			
		||||
      <td>{row.index}</td>
 | 
			
		||||
    </tr>))}</tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
  </>))}</>);
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@ -169,7 +169,7 @@ of column attribute objects and an array of row objects.  The former is used to
 | 
			
		||||
generate column headings and for indexing into the row objects.
 | 
			
		||||
 | 
			
		||||
The safest approach is to use an array of arrays for state and to generate
 | 
			
		||||
column objects that map to A1-style column headers.
 | 
			
		||||
column objects that map to A1-Style column headers.
 | 
			
		||||
 | 
			
		||||
The [React Data Grid demo](./grid#rows-and-columns-state) uses this approach
 | 
			
		||||
with the following column and row structure:
 | 
			
		||||
 | 
			
		||||
@ -161,7 +161,7 @@ of column attribute objects and an array of row objects.  The former is used to
 | 
			
		||||
generate column headings and for indexing into the row objects.
 | 
			
		||||
 | 
			
		||||
The safest approach is to use an array of arrays for state and to generate
 | 
			
		||||
column objects that map to A1-style column headers.
 | 
			
		||||
column objects that map to A1-Style column headers.
 | 
			
		||||
 | 
			
		||||
The [Vue Table Lite demo](./grid#rows-and-columns-bindings) uses this approach
 | 
			
		||||
with the following column and row structure:
 | 
			
		||||
 | 
			
		||||
@ -196,7 +196,7 @@ of column attribute objects and an array of row objects.  The former is used to
 | 
			
		||||
generate column headings and for indexing into the row objects.
 | 
			
		||||
 | 
			
		||||
The safest approach is to use an array of arrays for state and to generate
 | 
			
		||||
column objects that map to A1-style column headers.
 | 
			
		||||
column objects that map to A1-Style column headers.
 | 
			
		||||
 | 
			
		||||
`ngx-datatable` uses `prop` as the key and `name` for the column label:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										337
									
								
								docz/docs/03-demos/27-localfile.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										337
									
								
								docz/docs/03-demos/27-localfile.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,337 @@
 | 
			
		||||
---
 | 
			
		||||
sidebar_position: 26
 | 
			
		||||
title: Local File Access
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
Reading and writing files require native support.  `readFile` and `writeFile`
 | 
			
		||||
include support for some approaches but do not support every API.  When an API
 | 
			
		||||
is not supported by `readFile` or `writeFile`, the underlying `read` and
 | 
			
		||||
`write` methods can be used.
 | 
			
		||||
 | 
			
		||||
This demo looks at various web APIs.  More specific approaches for deployments
 | 
			
		||||
like mobile apps are covered in their respective demos.
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
 | 
			
		||||
Some snippets are also available in the "Common Use Cases" section:
 | 
			
		||||
 | 
			
		||||
- [Data Import](../solutions/input)
 | 
			
		||||
- [Data Export](../solutions/output)
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
:::warning
 | 
			
		||||
 | 
			
		||||
Not all web APIs are supported in all browsers.  For example, Firefox does not
 | 
			
		||||
support the "File System Access API".
 | 
			
		||||
 | 
			
		||||
Even when a browser technically supports a web API, it may be disabled in the
 | 
			
		||||
client browser. Some APIs do not give any feedback.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
## Binary Data
 | 
			
		||||
 | 
			
		||||
Modern browser APIs typically use typed arrays or `Blob` or `File` structures.
 | 
			
		||||
 | 
			
		||||
_Reading Binary Data_
 | 
			
		||||
 | 
			
		||||
Given a `Blob` or `File`, the underlying data cannot be read synchronously!
 | 
			
		||||
 | 
			
		||||
The callback-based approach uses a `FileReader`:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const reader = new FileReader();
 | 
			
		||||
reader.onload = function(e) {
 | 
			
		||||
  /* e.target.result is an ArrayBuffer */
 | 
			
		||||
  const wb = XLSX.read(e.target.result);
 | 
			
		||||
  console.log(XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]]));
 | 
			
		||||
}
 | 
			
		||||
reader.readAsArrayBuffer(file);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The Promise-based approach uses `Blob#arrayBuffer`:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
// usage: const wb = await blob_to_wb(blob);
 | 
			
		||||
async function blob_to_wb(blob) {
 | 
			
		||||
  return XLSX.read(await blob.arrayBuffer());
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
_Writing Binary Data_
 | 
			
		||||
 | 
			
		||||
`XLSX.write` can generate `Uint8Array` results by passing `type: "buffer"`.  A
 | 
			
		||||
`Blob` can be created by using the constructor:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const u8 = XLSX.write(workbook, { type: "buffer", bookType: "xlsx" });
 | 
			
		||||
const blob = new Blob([u8], { type: "application/vnd.ms-excel" });
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Web Workers
 | 
			
		||||
 | 
			
		||||
:::warning
 | 
			
		||||
 | 
			
		||||
**None of the browser methods work from Web Worker contexts!**
 | 
			
		||||
 | 
			
		||||
Data operations with the Web APIs must happen in the browser main thread.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
Web Workers and main thread can transfer `ArrayBuffer` or `Uint8Array` objects.
 | 
			
		||||
 | 
			
		||||
When generating a file, the worker will call `XLSX.write` with type `buffer`
 | 
			
		||||
and transfer the result to the main thread to initiate a download.
 | 
			
		||||
 | 
			
		||||
When parsing a file, the main thread will use the web API to read a `File` or
 | 
			
		||||
`Blob`, extract the underlying `ArrayBuffer` and transfer to the Web Worker.
 | 
			
		||||
 | 
			
		||||
## HTML5 Download Attribute
 | 
			
		||||
 | 
			
		||||
_Writing Files_
 | 
			
		||||
 | 
			
		||||
`writeFile` will attempt a download in the browser using the attribute.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
XLSX.writeFile(wb, "SheetJS.xlsx");
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## File API
 | 
			
		||||
 | 
			
		||||
_Reading Files_
 | 
			
		||||
 | 
			
		||||
In the `change` event of `<input type="file">`, `target` hold a list of files:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
async function handleFileAsync(e) {
 | 
			
		||||
  /* get first file */
 | 
			
		||||
  const file = e.target.files[0];
 | 
			
		||||
  /* get raw data */
 | 
			
		||||
  const data = await file.arrayBuffer();
 | 
			
		||||
  /* data is an ArrayBuffer */
 | 
			
		||||
  const workbook = XLSX.read(data);
 | 
			
		||||
  /* do something with the workbook here */
 | 
			
		||||
  console.log(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]))
 | 
			
		||||
}
 | 
			
		||||
input_dom_element.addEventListener("change", handleFileAsync, false);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## HTML Drag and Drop API
 | 
			
		||||
 | 
			
		||||
_Reading Files_
 | 
			
		||||
 | 
			
		||||
The `dataTransfer` property of the `drop` event holds a list of files:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
async function handleDropAsync(e) {
 | 
			
		||||
  e.stopPropagation(); e.preventDefault();
 | 
			
		||||
  /* get first file */
 | 
			
		||||
  const f = e.dataTransfer.files[0];
 | 
			
		||||
  /* get raw data */
 | 
			
		||||
  const data = await f.arrayBuffer();
 | 
			
		||||
  /* data is an ArrayBuffer */
 | 
			
		||||
  const wb = XLSX.read(data);
 | 
			
		||||
  /* do something with the workbook here */
 | 
			
		||||
  console.log(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]))
 | 
			
		||||
}
 | 
			
		||||
drop_dom_element.addEventListener("drop", handleDropAsync, false);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## File System Access API
 | 
			
		||||
 | 
			
		||||
_Reading Files_
 | 
			
		||||
 | 
			
		||||
`window.showOpenFilePicker` shows a file picker and resolves to an array of
 | 
			
		||||
file handles. When `multiple: false` is set, the array has one element.
 | 
			
		||||
 | 
			
		||||
The `getFile` method resolves to a `File` object whose data can be read with
 | 
			
		||||
the `arrayBuffer` method:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* Show picker and get data */
 | 
			
		||||
const [hFile] = await window.showOpenFilePicker({
 | 
			
		||||
  types: [{
 | 
			
		||||
    description: 'Spreadsheets',
 | 
			
		||||
    accept: { 'application/vnd.ms-excel': ['.xlsx', '.xls', '.xlsb', /*...*/] }
 | 
			
		||||
  }],
 | 
			
		||||
  excludeAcceptAllOption: true,
 | 
			
		||||
  multiple: false
 | 
			
		||||
});
 | 
			
		||||
const ab = await (await hFile.getFile()).arrayBuffer();
 | 
			
		||||
 | 
			
		||||
/* parse */
 | 
			
		||||
const wb = XLSX.read(ab);
 | 
			
		||||
 | 
			
		||||
/* do something with the workbook */
 | 
			
		||||
console.log(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]));
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
_Writing Files_
 | 
			
		||||
 | 
			
		||||
`window.showSaveFilePicker` shows a file picker and resolves to a file handle.
 | 
			
		||||
The `createWritable` method resolves to a `FileSystemWritableFileStream`, which
 | 
			
		||||
readily accepts `Uint8Array` data from `XLSX.write`:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* Show picker and get handle to file */
 | 
			
		||||
const hFile = await window.showSaveFilePicker({
 | 
			
		||||
  suggestedName: "SheetJS.xlsx",
 | 
			
		||||
  types: [
 | 
			
		||||
    { description: 'Excel 2007+ (XLSX)', accept: { 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': ['.xlsx'] } },
 | 
			
		||||
    { description: 'Excel 97-2004 (XLS)', accept: { 'application/vnd.ms-excel': ['.xls'] } },
 | 
			
		||||
    { description: 'Excel 2007+ Binary (XLSB)', accept: { 'application/vnd.ms-excel.sheet.binary.macroEnabled.12': ['.xlsb'] } },
 | 
			
		||||
    /* note that each MIME type must be unique! */
 | 
			
		||||
  ]
 | 
			
		||||
});
 | 
			
		||||
const wstream = await hFile.createWritable();
 | 
			
		||||
 | 
			
		||||
/* get extension */
 | 
			
		||||
const ext = hFile.name.slice(hFile.name.lastIndexOf(".")+1)
 | 
			
		||||
/* write */
 | 
			
		||||
wstream.write(XLSX.write(wb, { bookType: ext, type: "buffer" }))
 | 
			
		||||
/* close stream to commit file */
 | 
			
		||||
wstream.close();
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Demo
 | 
			
		||||
 | 
			
		||||
<details><summary><b>Live Example</b> (click to show) </summary>
 | 
			
		||||
 | 
			
		||||
This live example reads a file then tries to save as XLSX.
 | 
			
		||||
 | 
			
		||||
```jsx live
 | 
			
		||||
function SheetJSRoundTripFileSystemAPI() { return ( <button onClick={async () => {
 | 
			
		||||
  /* Show picker and get data */
 | 
			
		||||
  const [rFile] = await window.showOpenFilePicker({
 | 
			
		||||
    types: [{
 | 
			
		||||
      description: 'Spreadsheets',
 | 
			
		||||
      accept: { 'application/vnd.ms-excel': ['.xlsx', '.xls', '.xlsb', /*...*/] }
 | 
			
		||||
    }],
 | 
			
		||||
    excludeAcceptAllOption: true,
 | 
			
		||||
    multiple: false
 | 
			
		||||
  });
 | 
			
		||||
  const ab = await (await rFile.getFile()).arrayBuffer();
 | 
			
		||||
 | 
			
		||||
  /* parse */
 | 
			
		||||
  const wb = XLSX.read(ab);
 | 
			
		||||
 | 
			
		||||
  /* Show picker and get handle to file */
 | 
			
		||||
  const wFile = await window.showSaveFilePicker({
 | 
			
		||||
    suggestedName: "SheetJSRT.xlsx",
 | 
			
		||||
    types: [ { description: 'XLSX', accept: { 'application/vnd.ms-excel': ['.xlsx'] } } ]
 | 
			
		||||
  });
 | 
			
		||||
  console.log(wFile);
 | 
			
		||||
  const wstream = await wFile.createWritable();
 | 
			
		||||
 | 
			
		||||
  /* write */
 | 
			
		||||
  const buf = XLSX.write(wb, { bookType: "xlsx", type: "buffer" });
 | 
			
		||||
  wstream.write(buf);
 | 
			
		||||
 | 
			
		||||
  /* close stream to commit file */
 | 
			
		||||
  wstream.close();
 | 
			
		||||
 | 
			
		||||
}}>Click to read then save as XLSX</button> ) }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
## File and Directory Entries API
 | 
			
		||||
 | 
			
		||||
In the web browser, the File and Directory Entries API does not project to the
 | 
			
		||||
local file system. `cordova-plugin-file` *does* write to device in mobile apps!
 | 
			
		||||
 | 
			
		||||
_Writing Files_
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
// Request File System Access
 | 
			
		||||
window.requestFileSystem(window.PERSISTENT, 0, (fs) => {
 | 
			
		||||
  // Request a handle to "SheetJS.xlsx", making a new file if necessary
 | 
			
		||||
  fs.root.getFile("SheetJS.xlsx", {create: true}, entry => {
 | 
			
		||||
    // Request a FileWriter for writing data
 | 
			
		||||
    entry.createWriter(writer => {
 | 
			
		||||
      // The FileWriter API needs an actual Blob
 | 
			
		||||
      const u8 = XLSX.write(wb, { type: "buffer", bookType: "xlsx" });
 | 
			
		||||
      const data = new Blob([u8], { type: "application/vnd.ms-excel" });
 | 
			
		||||
      // `onwriteend` is called on success, `onerror` called on error
 | 
			
		||||
      writer.onwriteend = () => {}; writer.onerror = () => {};
 | 
			
		||||
      // write the data
 | 
			
		||||
      writer.write(data);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Internet Explorer
 | 
			
		||||
 | 
			
		||||
Internet Explorer offered proprietary APIs that were not adopted by Chromium.
 | 
			
		||||
 | 
			
		||||
#### Blob API
 | 
			
		||||
 | 
			
		||||
_Writing Files_
 | 
			
		||||
 | 
			
		||||
IE10 and IE11 support `navigator.msSaveBlob`. `writeFile` will use the method.
 | 
			
		||||
 | 
			
		||||
#### VBScript
 | 
			
		||||
 | 
			
		||||
_Reading and Writing Files_
 | 
			
		||||
 | 
			
		||||
Internet Explorer 6-9 with VBScript support `Scripting.FileSystemObject`.  This
 | 
			
		||||
is not supported in modern browsers.
 | 
			
		||||
 | 
			
		||||
This approach is implemented in the library `readFile` and `writeFile` methods.
 | 
			
		||||
It requires the shim script to be loaded before the main library script:
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<!-- load the shim script first -->
 | 
			
		||||
<script src="shim.min.js"></script>
 | 
			
		||||
<!-- then load the main script -->
 | 
			
		||||
<script src="xlsx.full.min.js"></script>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Other Platforms
 | 
			
		||||
 | 
			
		||||
### NodeJS
 | 
			
		||||
 | 
			
		||||
`fs.readFileSync` and `fs.writeFileSync` allow for reading and writing files.
 | 
			
		||||
 | 
			
		||||
When using `require`, these are supported in `readFile` and `writeFile`:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var XLSX = require("xlsx");
 | 
			
		||||
var wb = XLSX.readFile("sheetjs.numbers");
 | 
			
		||||
XLSX.writeFile(wb, "sheetjs.xls");
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[Installation](../getting-started/installation/nodejs) has a special note for
 | 
			
		||||
use with NodeJS ECMAScript Modules:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
import { readFile, writeFile, set_fs } from 'xlsx';
 | 
			
		||||
import * as fs from 'fs';
 | 
			
		||||
set_fs(fs);
 | 
			
		||||
 | 
			
		||||
var wb = XLSX.readFile("sheetjs.numbers");
 | 
			
		||||
XLSX.writeFile(wb, "sheetjs.xls");
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Deno
 | 
			
		||||
 | 
			
		||||
`Deno.readFileSync` and `Deno.writeFileSync` are supported by `readFile` and
 | 
			
		||||
`writeFile` out of the box:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
// @deno-types="https://cdn.sheetjs.com/xlsx-latest/package/types/index.d.ts"
 | 
			
		||||
import * as XLSX from 'https://cdn.sheetjs.com/xlsx-latest/package/xlsx.mjs';
 | 
			
		||||
 | 
			
		||||
const wb = XLSX.readFile("sheetjs.numbers");
 | 
			
		||||
XLSX.writeFile(wb, "sheetjs.xlsx");
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Apps
 | 
			
		||||
 | 
			
		||||
Desktop and mobile apps have their own specific APIs covered in separate demos:
 | 
			
		||||
 | 
			
		||||
- [Electron and other desktop apps](./desktop)
 | 
			
		||||
- [React Native and other mobile apps](./mobile)
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,7 @@ The demo projects include small runnable examples and short explainers.
 | 
			
		||||
- [`LocalStorage and SessionStorage`](./database#localstorage-and-sessionstorage)
 | 
			
		||||
- [`Web SQL Database`](./database#websql)
 | 
			
		||||
- [`IndexedDB`](./database#indexeddb)
 | 
			
		||||
- [`Local File Access`](./localfile)
 | 
			
		||||
 | 
			
		||||
### Frameworks
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -37,7 +37,7 @@ the ending col `16383`:
 | 
			
		||||
 | 
			
		||||
## A1-Style
 | 
			
		||||
 | 
			
		||||
A1-style is the default address style in Lotus 1-2-3 and Excel.
 | 
			
		||||
A1-Style is the default address style in Lotus 1-2-3 and Excel.
 | 
			
		||||
 | 
			
		||||
Columns are specified with letters, counting from `A` to `Z`, then `AA` to `ZZ`,
 | 
			
		||||
then `AAA`.  Some sample values, along with SheetJS column indices, are listed:
 | 
			
		||||
@ -126,7 +126,7 @@ var address = XLSX.utils.decode_cell("A2");
 | 
			
		||||
 | 
			
		||||
The argument is expected to be a string representing a single cell address.
 | 
			
		||||
 | 
			
		||||
_Generate an A1-style address string from a SheetJS cell address_
 | 
			
		||||
_Generate an A1-Style address string from a SheetJS cell address_
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var a1_addr = XLSX.utils.encode_cell({r:1, c:0});
 | 
			
		||||
@ -136,7 +136,7 @@ The argument is expected to be a SheetJS cell address
 | 
			
		||||
 | 
			
		||||
#### Cell Ranges
 | 
			
		||||
 | 
			
		||||
_Generate a SheetJS cell range from an A1-style range string_
 | 
			
		||||
_Generate a SheetJS cell range from an A1-Style range string_
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var range = XLSX.utils.decode_range("A1:D3");
 | 
			
		||||
@ -146,7 +146,7 @@ The argument is expected to be a string representing a range or a single cell
 | 
			
		||||
address.  The single cell address is interpreted as a single cell range, so
 | 
			
		||||
`XLSX.utils.decode_range("D3")` is the same as `XLSX.utils.decode_range("D3:D3")`
 | 
			
		||||
 | 
			
		||||
_Generate an A1-style address string from a SheetJS cell address_
 | 
			
		||||
_Generate an A1-Style address string from a SheetJS cell address_
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var a1_range = XLSX.utils.encode_range({ s: { c: 0, r: 0 }, e: { c: 3, r: 2 } });
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,7 @@ Cell objects are plain JS objects with keys and values following the convention:
 | 
			
		||||
| `z` | number format string associated with the cell (if requested)           |
 | 
			
		||||
| `w` | formatted text (if applicable)                                         |
 | 
			
		||||
|     | **Formulae** ([More Info](./features/formulae))                        |
 | 
			
		||||
| `f` | cell formula encoded as an A1-style string (if applicable)             |
 | 
			
		||||
| `f` | cell formula encoded as an A1-Style string (if applicable)             |
 | 
			
		||||
| `F` | range of enclosing array if formula is array formula (if applicable)   |
 | 
			
		||||
| `D` | if true, array formula is dynamic (if applicable)                      |
 | 
			
		||||
|     | **Other Cell Properties** ([More Info](./features))                    |
 | 
			
		||||
 | 
			
		||||
@ -80,7 +80,7 @@ XLSX.write(wb, {Props:{Author:"SheetJS"}});
 | 
			
		||||
|:----------|:-----------------------------------------------------------------|
 | 
			
		||||
| `Sheet`   | Name scope.  Sheet Index (0 = first sheet) or `null` (Workbook)  |
 | 
			
		||||
| `Name`    | Case-sensitive name.  Standard rules apply **                    |
 | 
			
		||||
| `Ref`     | A1-style Reference (`"Sheet1!$A$1:$D$20"`)                       |
 | 
			
		||||
| `Ref`     | A1-Style Reference (`"Sheet1!$A$1:$D$20"`)                       |
 | 
			
		||||
| `Comment` | Comment (only applicable for XLS/XLSX/XLSB)                      |
 | 
			
		||||
 | 
			
		||||
Excel allows two sheet-scoped defined names to share the same name.  However, a
 | 
			
		||||
 | 
			
		||||
@ -9,17 +9,17 @@ import TabItem from '@theme/TabItem';
 | 
			
		||||
 | 
			
		||||
<details><summary><b>Formulae File Format Support</b> (click to show)</summary>
 | 
			
		||||
 | 
			
		||||
The parser will translate from the storage representation to A1-style strings,
 | 
			
		||||
while the writer will translate from A1-style strings to the file format.
 | 
			
		||||
The parser will translate from the storage representation to A1-Style strings,
 | 
			
		||||
while the writer will translate from A1-Style strings to the file format.
 | 
			
		||||
 | 
			
		||||
| Formats           | Parse | Write | Array | Dynamic | Storage Representation |
 | 
			
		||||
|:------------------|:-----:|:-----:|:-----:|:-------:|:-----------------------|
 | 
			
		||||
| XLSX / XLSM       |   ✔   |   ✔   |   ✔   |    ✔    | A1-style strings       |
 | 
			
		||||
| XLSX / XLSM       |   ✔   |   ✔   |   ✔   |    ✔    | A1-Style strings       |
 | 
			
		||||
| XLSB              |   ✔   |       |   ✔   |    ✔    | BIFF parsed tokens     |
 | 
			
		||||
| XLS               |   ✔   |       |   ✔   |         | BIFF parsed tokens     |
 | 
			
		||||
| XLML              |   ✔   |   ✔   |   ✔   |         | RC-style strings       |
 | 
			
		||||
| SYLK              |   ✔   |   ✔   |       |         | A1 / RC-style strings  |
 | 
			
		||||
| CSV / TXT         |   ✔   |   ✔   |       |         | A1-style strings       |
 | 
			
		||||
| CSV / TXT         |   ✔   |   ✔   |       |         | A1-Style strings       |
 | 
			
		||||
| ODS / FODS / UOS  |   ✔   |   ✔   |       |         | OpenFormula strings    |
 | 
			
		||||
| WK\*              |   ✔   |       |       |         | Lotus parsed tokens    |
 | 
			
		||||
| WQ\* / WB\* / QPW |       |       |       |         | Quattro Pro tokens     |
 | 
			
		||||
@ -124,7 +124,7 @@ const workbook = XLSX.readFile("test.xlsx", { cellFormula: true });
 | 
			
		||||
 | 
			
		||||
## A1-Style Formulae
 | 
			
		||||
 | 
			
		||||
The A1-style formula string is stored in the `f` field of the cell object.
 | 
			
		||||
The A1-Style formula string is stored in the `f` field of the cell object.
 | 
			
		||||
Spreadsheet software typically represent formulae with a leading `=` sign, but
 | 
			
		||||
SheetJS formulae omit the `=`.
 | 
			
		||||
 | 
			
		||||
@ -132,7 +132,7 @@ SheetJS formulae omit the `=`.
 | 
			
		||||
 | 
			
		||||
For example, consider [this test file](pathname:///files/concat.xlsx):
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
```jsx live
 | 
			
		||||
/* The live editor requires this function wrapper */
 | 
			
		||||
 | 
			
		||||
@ -65,7 +65,7 @@ The read functions accept an options argument:
 | 
			
		||||
  for files employing other encryption methods.
 | 
			
		||||
- Newer Excel functions are serialized with the `_xlfn.` prefix, hidden from the
 | 
			
		||||
  user. SheetJS will strip `_xlfn.` normally. The `xlfn` option preserves them.
 | 
			
		||||
- WTF is mainly for development.  By default, the parser will suppress read
 | 
			
		||||
- `WTF` is mainly for development.  By default, the parser will suppress read
 | 
			
		||||
  errors on single worksheets, allowing you to read from the worksheets that do
 | 
			
		||||
  parse properly. Setting `WTF:true` forces those errors to be thrown.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -78,7 +78,7 @@ accepts an options argument:
 | 
			
		||||
| `origin`         | Description                                               |
 | 
			
		||||
| :--------------- | :-------------------------------------------------------- |
 | 
			
		||||
| (cell object)    | Use specified cell (cell object)                          |
 | 
			
		||||
| (string)         | Use specified cell (A1-style cell)                        |
 | 
			
		||||
| (string)         | Use specified cell (A1-Style cell)                        |
 | 
			
		||||
| (number >= 0)    | Start from the first column at specified row (0-indexed)  |
 | 
			
		||||
| -1               | Append to bottom of worksheet starting on first column    |
 | 
			
		||||
| (default)        | Start from cell A1                                        |
 | 
			
		||||
@ -203,7 +203,7 @@ an options argument:
 | 
			
		||||
| `origin`         | Description                                               |
 | 
			
		||||
| :--------------- | :-------------------------------------------------------- |
 | 
			
		||||
| (cell object)    | Use specified cell (cell object)                          |
 | 
			
		||||
| (string)         | Use specified cell (A1-style cell)                        |
 | 
			
		||||
| (string)         | Use specified cell (A1-Style cell)                        |
 | 
			
		||||
| (number >= 0)    | Start from the first column at specified row (0-indexed)  |
 | 
			
		||||
| -1               | Append to bottom of worksheet starting on first column    |
 | 
			
		||||
| (default)        | Start from cell A1                                        |
 | 
			
		||||
@ -352,7 +352,7 @@ an options argument:
 | 
			
		||||
| `origin`         | Description                                               |
 | 
			
		||||
| :--------------- | :-------------------------------------------------------- |
 | 
			
		||||
| (cell object)    | Use specified cell (cell object)                          |
 | 
			
		||||
| (string)         | Use specified cell (A1-style cell)                        |
 | 
			
		||||
| (string)         | Use specified cell (A1-Style cell)                        |
 | 
			
		||||
| (number >= 0)    | Start from the first column at specified row (0-indexed)  |
 | 
			
		||||
| -1               | Append to bottom of worksheet starting on first column    |
 | 
			
		||||
| (default)        | Start from cell A1                                        |
 | 
			
		||||
@ -559,7 +559,7 @@ takes an options argument:
 | 
			
		||||
| `range`          | Description                                               |
 | 
			
		||||
| :--------------- | :-------------------------------------------------------- |
 | 
			
		||||
| (number)         | Use worksheet range but set starting row to the value     |
 | 
			
		||||
| (string)         | Use specified range (A1-style bounded range string)       |
 | 
			
		||||
| (string)         | Use specified range (A1-Style bounded range string)       |
 | 
			
		||||
| (default)        | Use worksheet range (`ws['!ref']`)                        |
 | 
			
		||||
 | 
			
		||||
`header` is expected to be one of:
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@ hide_table_of_contents: true
 | 
			
		||||
 | 
			
		||||
# File Formats
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||

 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
@ -48,17 +48,17 @@ range limits will be silently truncated:
 | 
			
		||||
 | 
			
		||||
| Format                                    | Last Cell  | Max Cols | Max Rows |
 | 
			
		||||
|:------------------------------------------|:-----------|---------:|---------:|
 | 
			
		||||
| Excel 2007+ XML Formats (XLSX/XLSM)       | XFD1048576 |    16384 |  1048576 |
 | 
			
		||||
| Excel 2007+ Binary Format (XLSB BIFF12)   | XFD1048576 |    16384 |  1048576 |
 | 
			
		||||
| Numbers 12.1 (NUMBERS)                    | ALL1000000 |     1000 |  1000000 |
 | 
			
		||||
| Quattro Pro 9+ (QPW)                      | IV1000000  |      256 |  1000000 |
 | 
			
		||||
| Excel 97-2004 (XLS BIFF8)                 | IV65536    |      256 |    65536 |
 | 
			
		||||
| Excel 5.0/95 (XLS BIFF5)                  | IV16384    |      256 |    16384 |
 | 
			
		||||
| Excel 4.0 (XLS BIFF4)                     | IV16384    |      256 |    16384 |
 | 
			
		||||
| Excel 3.0 (XLS BIFF3)                     | IV16384    |      256 |    16384 |
 | 
			
		||||
| Excel 2.0/2.1 (XLS BIFF2)                 | IV16384    |      256 |    16384 |
 | 
			
		||||
| Lotus 1-2-3 R2 - R5 (WK1/WK3/WK4)         | IV8192     |      256 |     8192 |
 | 
			
		||||
| Lotus 1-2-3 R1 (WKS)                      | IV2048     |      256 |     2048 |
 | 
			
		||||
| Excel 2007+ XML Formats (XLSX/XLSM)       |`XFD1048576`|    16384 |  1048576 |
 | 
			
		||||
| Excel 2007+ Binary Format (XLSB BIFF12)   |`XFD1048576`|    16384 |  1048576 |
 | 
			
		||||
| Numbers 12.1 (NUMBERS)                    |`ALL1000000`|     1000 |  1000000 |
 | 
			
		||||
| Quattro Pro 9+ (QPW)                      |`IV1000000 `|      256 |  1000000 |
 | 
			
		||||
| Excel 97-2004 (XLS BIFF8)                 |`IV65536   `|      256 |    65536 |
 | 
			
		||||
| Excel 5.0/95 (XLS BIFF5)                  |`IV16384   `|      256 |    16384 |
 | 
			
		||||
| Excel 4.0 (XLS BIFF4)                     |`IV16384   `|      256 |    16384 |
 | 
			
		||||
| Excel 3.0 (XLS BIFF3)                     |`IV16384   `|      256 |    16384 |
 | 
			
		||||
| Excel 2.0/2.1 (XLS BIFF2)                 |`IV16384   `|      256 |    16384 |
 | 
			
		||||
| Lotus 1-2-3 R2 - R5 (WK1/WK3/WK4)         |`IV8192    `|      256 |     8192 |
 | 
			
		||||
| Lotus 1-2-3 R1 (WKS)                      |`IV2048    `|      256 |     2048 |
 | 
			
		||||
 | 
			
		||||
Excel 2003 SpreadsheetML range limits are governed by the version of Excel and
 | 
			
		||||
are not enforced by the writer.
 | 
			
		||||
@ -208,7 +208,7 @@ files compatible with Visual FoxPro extensions.
 | 
			
		||||
 | 
			
		||||
Multi-file extensions like external memos and tables are currently unsupported,
 | 
			
		||||
limited by the general ability to read arbitrary files in the web browser.  The
 | 
			
		||||
reader understands DBF Level 7 extensions like DATETIME.
 | 
			
		||||
reader understands DBF Level 7 extensions like `DATETIME`.
 | 
			
		||||
 | 
			
		||||
#### Symbolic Link (SYLK)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -86,7 +86,7 @@ Tests utilize the mocha testing framework.
 | 
			
		||||
 - <https://saucelabs.com/u/sheetjs> for XLS\* modules using Sauce Labs
 | 
			
		||||
 | 
			
		||||
The test suite also includes tests for various time zones.  To change
 | 
			
		||||
the timezone locally, set the TZ environment variable:
 | 
			
		||||
the timezone locally, set the `TZ` environment variable:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
$ env TZ="Asia/Kolkata" WTF=1 make test_misc
 | 
			
		||||
@ -107,5 +107,5 @@ files snapshot from [the repo](https://github.com/SheetJS/test_files/releases)
 | 
			
		||||
 | 
			
		||||
<http://github.com/SheetJS/test_files/releases/download/20170409/test_files.zip>
 | 
			
		||||
 | 
			
		||||
(download and unzip to the `test_files` subdirectory)
 | 
			
		||||
(download and unzip to the `test_files` subfolder)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -39,7 +39,7 @@ import TabItem from '@theme/TabItem';
 | 
			
		||||
<Tabs>
 | 
			
		||||
  <TabItem value="wsl" label="Windows WSL">
 | 
			
		||||
 | 
			
		||||
The OSX/Linux workflow works in WSL.  Initial setup is involved:
 | 
			
		||||
The MacOS/Linux workflow works in WSL.  Initial setup is involved:
 | 
			
		||||
 | 
			
		||||
1) Install mercurial and subversion.
 | 
			
		||||
 | 
			
		||||
@ -66,7 +66,7 @@ sudo n 16
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
3) follow <https://github.com/paul-nelson-baker/git-openssl-shellscript> to
 | 
			
		||||
build and install a version of Git with OpenSSL:
 | 
			
		||||
build and install a version of Git with proper SSL support:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
# Git does not support OpenSSL out of the box, must do this
 | 
			
		||||
@ -75,10 +75,10 @@ chmod +x compile-git-with-openssl.sh
 | 
			
		||||
./compile-git-with-openssl.sh
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
(instructions continued in the OSX/Linux part)
 | 
			
		||||
(instructions continued in the MacOS/Linux part)
 | 
			
		||||
 | 
			
		||||
  </TabItem>
 | 
			
		||||
  <TabItem value="osx" label="OSX/Linux">
 | 
			
		||||
  <TabItem value="osx" label="MacOS/Linux">
 | 
			
		||||
 | 
			
		||||
Initial setup:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -8,9 +8,9 @@ title: Overview
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
[](https://github.com/SheetJS/sheetjs/actions)
 | 
			
		||||
[](https://snyk.io/test/github/SheetJS/sheetjs)
 | 
			
		||||
[](https://snyk.io/test/github/SheetJS/sheetjs)
 | 
			
		||||
[](https://cdn.sheetjs.com/)
 | 
			
		||||
[](https://github.com/SheetJS/sheetjs)
 | 
			
		||||
[](https://github.com/SheetJS/sheetjs)
 | 
			
		||||
 | 
			
		||||
SheetJS Community Edition offers battle-tested open-source solutions for
 | 
			
		||||
extracting useful data from almost any complex spreadsheet and generating new
 | 
			
		||||
@ -220,6 +220,6 @@ This,is,a,Test
 | 
			
		||||
 | 
			
		||||
### Supported File Formats
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||

 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
@ -4,51 +4,51 @@ var XLSX = require('xlsx');
 | 
			
		||||
var Busboy = require('busboy');
 | 
			
		||||
 | 
			
		||||
exports.handler = function(event, context, callback) {
 | 
			
		||||
	if(event.requestContext.http.method == "GET") {
 | 
			
		||||
		/* make workbook */
 | 
			
		||||
		var wb = XLSX.read("S,h,e,e,t,J,S\n5,4,3,3,7,9,5", {type: "binary"});
 | 
			
		||||
		/* write to XLSX file in base64 encoding */
 | 
			
		||||
		var body = XLSX.write(wb, {type:"base64", bookType: "xlsx"});
 | 
			
		||||
		/* mark as attached file */
 | 
			
		||||
		var headers = { "Content-Disposition": 'attachment; filename="SheetJSLambda.xlsx"'};
 | 
			
		||||
		/* Send back data */
 | 
			
		||||
		callback(null, {
 | 
			
		||||
			statusCode: 200,
 | 
			
		||||
			isBase64Encoded: true,
 | 
			
		||||
			body: body,
 | 
			
		||||
			headers: headers
 | 
			
		||||
		});
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
  if(event.requestContext.http.method == "GET") {
 | 
			
		||||
    /* make workbook */
 | 
			
		||||
    var wb = XLSX.read("S,h,e,e,t,J,S\n5,4,3,3,7,9,5", {type: "binary"});
 | 
			
		||||
    /* write to XLSX file in base64 encoding */
 | 
			
		||||
    var body = XLSX.write(wb, {type:"base64", bookType: "xlsx"});
 | 
			
		||||
    /* mark as attached file */
 | 
			
		||||
    var headers = { "Content-Disposition": 'attachment; filename="SheetJSLambda.xlsx"'};
 | 
			
		||||
    /* Send back data */
 | 
			
		||||
    callback(null, {
 | 
			
		||||
      statusCode: 200,
 | 
			
		||||
      isBase64Encoded: true,
 | 
			
		||||
      body: body,
 | 
			
		||||
      headers: headers
 | 
			
		||||
    });
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
	/* set up busboy */
 | 
			
		||||
	var ctype = event.headers['Content-Type']||event.headers['content-type'];
 | 
			
		||||
	var bb = Busboy({headers:{'content-type':ctype}});
 | 
			
		||||
  /* set up busboy */
 | 
			
		||||
  var ctype = event.headers['Content-Type']||event.headers['content-type'];
 | 
			
		||||
  var bb = Busboy({headers:{'content-type':ctype}});
 | 
			
		||||
 | 
			
		||||
	/* busboy is evented; accumulate the fields and files manually */
 | 
			
		||||
	var fields = {}, files = {};
 | 
			
		||||
	bb.on('error', function(err) { callback(null, { body: err.message }); });
 | 
			
		||||
	bb.on('field', function(fieldname, val) {fields[fieldname] = val });
 | 
			
		||||
	bb.on('file', function(fieldname, file, filename) {
 | 
			
		||||
		/* concatenate the individual data buffers */
 | 
			
		||||
		var buffers = [];
 | 
			
		||||
		file.on('data', function(data) { buffers.push(data); });
 | 
			
		||||
		file.on('end', function() { files[fieldname] = [Buffer.concat(buffers), filename]; });
 | 
			
		||||
	});
 | 
			
		||||
  /* busboy is evented; accumulate the fields and files manually */
 | 
			
		||||
  var fields = {}, files = {};
 | 
			
		||||
  bb.on('error', function(err) { callback(null, { body: err.message }); });
 | 
			
		||||
  bb.on('field', function(fieldname, val) {fields[fieldname] = val });
 | 
			
		||||
  bb.on('file', function(fieldname, file, filename) {
 | 
			
		||||
    /* concatenate the individual data buffers */
 | 
			
		||||
    var buffers = [];
 | 
			
		||||
    file.on('data', function(data) { buffers.push(data); });
 | 
			
		||||
    file.on('end', function() { files[fieldname] = [Buffer.concat(buffers), filename]; });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
	/* on the finish event, all of the fields and files are ready */
 | 
			
		||||
	bb.on('finish', function() {
 | 
			
		||||
		/* grab the first file */
 | 
			
		||||
		var f = files["upload"];
 | 
			
		||||
		if(!f) callback(new Error("Must submit a file for processing!"));
 | 
			
		||||
  /* on the finish event, all of the fields and files are ready */
 | 
			
		||||
  bb.on('finish', function() {
 | 
			
		||||
    /* grab the first file */
 | 
			
		||||
    var f = files["upload"];
 | 
			
		||||
    if(!f) callback(new Error("Must submit a file for processing!"));
 | 
			
		||||
 | 
			
		||||
		/* f[0] is a buffer */
 | 
			
		||||
		var wb = XLSX.read(f[0]);
 | 
			
		||||
    /* f[0] is a buffer */
 | 
			
		||||
    var wb = XLSX.read(f[0]);
 | 
			
		||||
 | 
			
		||||
		/* grab first worksheet and convert to CSV */
 | 
			
		||||
		var ws = wb.Sheets[wb.SheetNames[0]];
 | 
			
		||||
		callback(null, { statusCode: 200, body: XLSX.utils.sheet_to_csv(ws) });
 | 
			
		||||
	});
 | 
			
		||||
    /* grab first worksheet and convert to CSV */
 | 
			
		||||
    var ws = wb.Sheets[wb.SheetNames[0]];
 | 
			
		||||
    callback(null, { statusCode: 200, body: XLSX.utils.sheet_to_csv(ws) });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
	bb.end(Buffer.from(event.body, "base64"));
 | 
			
		||||
  bb.end(Buffer.from(event.body, "base64"));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -1,26 +1,26 @@
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
 | 
			
		||||
	<defs>
 | 
			
		||||
		<clipPath id="grid"><polygon points="0,0 0,1024 1024,1024 1024,780"/></clipPath>
 | 
			
		||||
		<clipPath id="bars"><polygon points="0,0 1024,0 1024,780"/></clipPath>
 | 
			
		||||
	</defs>
 | 
			
		||||
	<polygon fill="#ffffff" points="0,0 0,1024 1024,1024 1024,0"/>
 | 
			
		||||
	<polygon fill="#63deab" stroke="#ffffff" stroke-width="10" points="0,0 0,1024 1024,1024 1024,780"/>
 | 
			
		||||
	<g clip-path="url(#bars)">
 | 
			
		||||
		<rect x="288" y="160" width="192" height="1000" fill="#a2c5f0" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
		<rect x="544" y="288" width="192" height="1000" fill="#ffbdbd" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
		<rect x="800" y="64"  width="192" height="1000" fill="#a2c5f0" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
	</g>
 | 
			
		||||
	<g clip-path="url(#grid)">
 | 
			
		||||
		<line x1="0" y1="128" x2="1024" y2="128" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
		<line x1="0" y1="256" x2="1024" y2="256" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
		<line x1="0" y1="384" x2="1024" y2="384" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
		<line x1="0" y1="512" x2="1024" y2="512" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
		<line x1="0" y1="640" x2="1024" y2="640" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
		<line x1="0" y1="768" x2="1024" y2="768" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
		<line x1="0" y1="896" x2="1024" y2="896" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
		<line x1="256" y1="0" x2="256" y2="1024" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
		<line x1="512" y1="0" x2="512" y2="1024" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
		<line x1="768" y1="0" x2="768" y2="1024" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
	</g>
 | 
			
		||||
	<line x1="0" y1="0" x2="1024" y2="780" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
  <defs>
 | 
			
		||||
    <clipPath id="grid"><polygon points="0,0 0,1024 1024,1024 1024,780"/></clipPath>
 | 
			
		||||
    <clipPath id="bars"><polygon points="0,0 1024,0 1024,780"/></clipPath>
 | 
			
		||||
  </defs>
 | 
			
		||||
  <polygon fill="#ffffff" points="0,0 0,1024 1024,1024 1024,0"/>
 | 
			
		||||
  <polygon fill="#63deab" stroke="#ffffff" stroke-width="10" points="0,0 0,1024 1024,1024 1024,780"/>
 | 
			
		||||
  <g clip-path="url(#bars)">
 | 
			
		||||
    <rect x="288" y="160" width="192" height="1000" fill="#a2c5f0" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
    <rect x="544" y="288" width="192" height="1000" fill="#ffbdbd" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
    <rect x="800" y="64"  width="192" height="1000" fill="#a2c5f0" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
  </g>
 | 
			
		||||
  <g clip-path="url(#grid)">
 | 
			
		||||
    <line x1="0" y1="128" x2="1024" y2="128" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
    <line x1="0" y1="256" x2="1024" y2="256" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
    <line x1="0" y1="384" x2="1024" y2="384" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
    <line x1="0" y1="512" x2="1024" y2="512" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
    <line x1="0" y1="640" x2="1024" y2="640" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
    <line x1="0" y1="768" x2="1024" y2="768" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
    <line x1="0" y1="896" x2="1024" y2="896" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
    <line x1="256" y1="0" x2="256" y2="1024" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
    <line x1="512" y1="0" x2="512" y2="1024" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
    <line x1="768" y1="0" x2="768" y2="1024" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
  </g>
 | 
			
		||||
  <line x1="0" y1="0" x2="1024" y2="780" stroke="#ffffff" stroke-width="10" />
 | 
			
		||||
</svg>
 | 
			
		||||
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.7 KiB  | 
		Loading…
	
		Reference in New Issue
	
	Block a user