docusaurus
| @ -5,6 +5,7 @@ js-xlsx | ||||
| xls | ||||
| xlsb | ||||
| xlsx | ||||
| docs.sheetjs.com | ||||
| 
 | ||||
| # Excel-related terms | ||||
| A1-style | ||||
| @ -48,6 +49,7 @@ NPM | ||||
| Nuxt | ||||
| PhantomJS | ||||
| Photoshop | ||||
| ReactJS | ||||
| Redis | ||||
| RequireJS | ||||
| Rollup | ||||
| @ -58,6 +60,7 @@ VueJS | ||||
| WebKit | ||||
| WebSQL | ||||
| WK_ | ||||
| axios | ||||
| iOS | ||||
| iWork | ||||
| nodejs | ||||
|  | ||||
							
								
								
									
										8
									
								
								Makefile
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -1,3 +1,9 @@ | ||||
| .PHONY: build | ||||
| build: | ||||
| 	cd docz; pnpm build; cd .. | ||||
| 	rm -rf docs | ||||
| 	mv docz/build/ docs | ||||
| 
 | ||||
| .PHONY: index | ||||
| index: readme ## Rebuild site
 | ||||
| 	sed -i .bak 's/](d/](https:\/\/github.com\/SheetJS\/SheetJS\/tree\/master\/d/g' README.md | ||||
| @ -21,7 +27,7 @@ formats.png legend.png: %.png: misc/%.svg | ||||
| 	node misc/coarsify.js misc/$*.svg misc/$*.svg.svg | ||||
| 	npx svgexport misc/$*.svg.svg $@ 0.5x | ||||
| 
 | ||||
| MDLINT=README.md | ||||
| MDLINT=README.md $(wildcard docz/*.md*) $(wildcard docz/docs/*.md*) $(wildcard docz/docs/*/*.md*) | ||||
| .PHONY: mdlint | ||||
| mdlint: $(MDLINT) ## Check markdown documents
 | ||||
| 	npx alex $^ | ||||
|  | ||||
							
								
								
									
										20
									
								
								docz/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,20 @@ | ||||
| # Dependencies | ||||
| /node_modules | ||||
| 
 | ||||
| # Production | ||||
| /build | ||||
| 
 | ||||
| # Generated files | ||||
| .docusaurus | ||||
| .cache-loader | ||||
| 
 | ||||
| # Misc | ||||
| .DS_Store | ||||
| .env.local | ||||
| .env.development.local | ||||
| .env.test.local | ||||
| .env.production.local | ||||
| 
 | ||||
| npm-debug.log* | ||||
| yarn-debug.log* | ||||
| yarn-error.log* | ||||
							
								
								
									
										3
									
								
								docz/README.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,3 @@ | ||||
| # docs.sheetjs.com | ||||
| 
 | ||||
| <https://docs.sheetjs.com/> | ||||
							
								
								
									
										3
									
								
								docz/babel.config.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,3 @@ | ||||
| module.exports = { | ||||
|   presets: [require.resolve('@docusaurus/core/lib/babel/preset')], | ||||
| }; | ||||
							
								
								
									
										12
									
								
								docz/blog/2019-05-28-first-blog-post.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,12 @@ | ||||
| --- | ||||
| slug: first-blog-post | ||||
| title: First Blog Post | ||||
| authors: | ||||
|   name: Gao Wei | ||||
|   title: Docusaurus Core Team | ||||
|   url: https://github.com/wgao19 | ||||
|   image_url: https://github.com/wgao19.png | ||||
| tags: [hola, docusaurus] | ||||
| --- | ||||
| 
 | ||||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet | ||||
							
								
								
									
										44
									
								
								docz/blog/2019-05-29-long-blog-post.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,44 @@ | ||||
| --- | ||||
| slug: long-blog-post | ||||
| title: Long Blog Post | ||||
| authors: endi | ||||
| tags: [hello, docusaurus] | ||||
| --- | ||||
| 
 | ||||
| This is the summary of a very long blog post, | ||||
| 
 | ||||
| Use a `<!--` `truncate` `-->` comment to limit blog post size in the list view. | ||||
| 
 | ||||
| <!--truncate--> | ||||
| 
 | ||||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet | ||||
| 
 | ||||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet | ||||
| 
 | ||||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet | ||||
| 
 | ||||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet | ||||
| 
 | ||||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet | ||||
| 
 | ||||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet | ||||
| 
 | ||||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet | ||||
| 
 | ||||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet | ||||
| 
 | ||||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet | ||||
| 
 | ||||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet | ||||
| 
 | ||||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet | ||||
| 
 | ||||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet | ||||
| 
 | ||||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet | ||||
| 
 | ||||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet | ||||
| 
 | ||||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet | ||||
| 
 | ||||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet | ||||
							
								
								
									
										20
									
								
								docz/blog/2021-08-01-mdx-blog-post.mdx
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,20 @@ | ||||
| --- | ||||
| slug: mdx-blog-post | ||||
| title: MDX Blog Post | ||||
| authors: [slorber] | ||||
| tags: [docusaurus] | ||||
| --- | ||||
| 
 | ||||
| Blog posts support [Docusaurus Markdown features](https://docusaurus.io/docs/markdown-features), such as [MDX](https://mdxjs.com/). | ||||
| 
 | ||||
| :::tip | ||||
| 
 | ||||
| Use the power of React to create interactive blog posts. | ||||
| 
 | ||||
| ```js | ||||
| <button onClick={() => alert('button clicked!')}>Click me!</button> | ||||
| ``` | ||||
| 
 | ||||
| <button onClick={() => alert('button clicked!')}>Click me!</button> | ||||
| 
 | ||||
| ::: | ||||
							
								
								
									
										
											BIN
										
									
								
								docz/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg
									
									
									
									
									
										Normal file
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						| After Width: | Height: | Size: 94 KiB | 
							
								
								
									
										25
									
								
								docz/blog/2021-08-26-welcome/index.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,25 @@ | ||||
| --- | ||||
| slug: welcome | ||||
| title: Welcome | ||||
| authors: [slorber, yangshun] | ||||
| tags: [facebook, hello, docusaurus] | ||||
| --- | ||||
| 
 | ||||
| [Docusaurus blogging features](https://docusaurus.io/docs/blog) are powered by the [blog plugin](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-blog). | ||||
| 
 | ||||
| Simply add Markdown files (or folders) to the `blog` directory. | ||||
| 
 | ||||
| Regular blog authors can be added to `authors.yml`. | ||||
| 
 | ||||
| The blog post date can be extracted from filenames, such as: | ||||
| 
 | ||||
| - `2019-05-30-welcome.md` | ||||
| - `2019-05-30-welcome/index.md` | ||||
| 
 | ||||
| A blog post folder can be convenient to co-locate blog post images: | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| The blog supports tags as well! | ||||
| 
 | ||||
| **And if you don't want a blog**: just delete this directory, and use `blog: false` in your Docusaurus config. | ||||
							
								
								
									
										17
									
								
								docz/blog/authors.yml
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,17 @@ | ||||
| endi: | ||||
|   name: Endilie Yacop Sucipto | ||||
|   title: Maintainer of Docusaurus | ||||
|   url: https://github.com/endiliey | ||||
|   image_url: https://github.com/endiliey.png | ||||
| 
 | ||||
| yangshun: | ||||
|   name: Yangshun Tay | ||||
|   title: Front End Engineer @ Facebook | ||||
|   url: https://github.com/yangshun | ||||
|   image_url: https://github.com/yangshun.png | ||||
| 
 | ||||
| slorber: | ||||
|   name: Sébastien Lorber | ||||
|   title: Docusaurus maintainer | ||||
|   url: https://sebastienlorber.com | ||||
|   image_url: https://github.com/slorber.png | ||||
							
								
								
									
										112
									
								
								docz/docs/02-installation/01-standalone.mdx
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,112 @@ | ||||
| --- | ||||
| sidebar_position: 1 | ||||
| sidebar_custom_props: | ||||
|   summary: Classic pages with simple <script> tags | ||||
| --- | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| 
 | ||||
| # Standalone Browser Scripts | ||||
| 
 | ||||
| Each standalone release script is available at <https://cdn.sheetjs.com/>. | ||||
| 
 | ||||
| <div>The current version is {current} and can be referenced as follows:</div> | ||||
| 
 | ||||
| <pre><code parentName="pre" {...{"className": "language-html"}}>{`\ | ||||
| <!-- use version ${current} --> | ||||
| <script lang="javascript" src="https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js"></script>`} | ||||
| </code></pre> | ||||
| 
 | ||||
| The `latest` tag references the latest version and updates with each release: | ||||
| 
 | ||||
| ```html | ||||
| <!-- use the latest version --> | ||||
| <script lang="javascript" src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"></script> | ||||
| ``` | ||||
| 
 | ||||
| **For production use, scripts should be downloaded and added to a public folder | ||||
| alongside other scripts.** | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Download using Bower</b> (click to show)</summary> | ||||
| 
 | ||||
| [Bower](https://bower.io/) plays nice with the CDN tarballs: | ||||
| 
 | ||||
| <pre><code parentName="pre" {...{"className": "language-bash"}}>{`\ | ||||
| $ npx bower install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| </code></pre> | ||||
| 
 | ||||
| Bower will place the standalone scripts in `bower_components/js-xlsx/dist/` | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Browser builds</b> (click to show)</summary> | ||||
| 
 | ||||
| The complete single-file version is generated at `dist/xlsx.full.min.js` | ||||
| 
 | ||||
| `dist/xlsx.core.min.js` omits codepage library (no support for XLS encodings) | ||||
| 
 | ||||
| A slimmer build is generated at `dist/xlsx.mini.min.js`. Compared to full build: | ||||
| - codepage library skipped (no support for XLS encodings) | ||||
| - no support for XLSB / XLS / Lotus 1-2-3 / SpreadsheetML 2003 / Numbers | ||||
| - node stream utils removed | ||||
| 
 | ||||
| These scripts are also available on the CDN: | ||||
| 
 | ||||
| <pre><code parentName="pre" {...{"className": "language-html"}}>{`\ | ||||
| <!-- use xlsx.mini.min.js from version ${current} --> | ||||
| <script lang="javascript" src="https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.mini.min.js"></script>`} | ||||
| </code></pre> | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Internet Explorer and ECMAScript 3 Compatibility</b> (click to show)</summary> | ||||
| 
 | ||||
| For broad compatibility with JavaScript engines, the library is written using | ||||
| ECMAScript 3 language dialect as well as some ES5 features like `Array#forEach`. | ||||
| Older browsers require shims to provide missing functions. | ||||
| 
 | ||||
| To use the shim, add the shim before the script tag that loads `xlsx.js`: | ||||
| 
 | ||||
| ```html | ||||
| <!-- add the shim first --> | ||||
| <script type="text/javascript" src="shim.min.js"></script> | ||||
| <!-- after the shim is referenced, add the library --> | ||||
| <script type="text/javascript" src="xlsx.full.min.js"></script> | ||||
| ``` | ||||
| 
 | ||||
| Due to SSL certificate compatibility issues, it is highly recommended to save | ||||
| the Standalone and Shim scripts from <https://cdn.sheetjs.com/> and add to a | ||||
| public directory in the site. | ||||
| 
 | ||||
| The script also includes `IE_LoadFile` and `IE_SaveFile` for loading and saving | ||||
| files in Internet Explorer versions 6-9.  The `xlsx.extendscript.js` script | ||||
| bundles the shim in a format suitable for Photoshop and other Adobe products. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>ECMAScript Module Imports in a SCRIPT TAG</b> (click to show)</summary> | ||||
| 
 | ||||
| The ECMAScript Module build is saved to `xlsx.mjs` and can be directly added to | ||||
| a page with a `script` tag using `type="module"`: | ||||
| 
 | ||||
| <pre><code parentName="pre" {...{"className": "language-html"}}>{`\ | ||||
| <script type="module"> | ||||
| import { read, writeFileXLSX } from "https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs"; | ||||
| </script>`} | ||||
| </code></pre> | ||||
| 
 | ||||
| If XLS support is required, `cpexcel.full.js` must be manually imported: | ||||
| 
 | ||||
| <pre><code parentName="pre" {...{"className": "language-html"}}>{`\ | ||||
| <script type="module"> | ||||
| /* load the codepage support library for extended support with older formats  */ | ||||
| import { set_cptable } from "https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs"; | ||||
| import * as cptable from 'https://cdn.sheetjs.com/xlsx-${current}/package/dist/cpexcel.full.mjs'; | ||||
| set_cptable(cptable); | ||||
| </script>`} | ||||
| </code></pre> | ||||
| 
 | ||||
| </details> | ||||
							
								
								
									
										54
									
								
								docz/docs/02-installation/02-frameworks.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,54 @@ | ||||
| --- | ||||
| sidebar_position: 2 | ||||
| sidebar_custom_props: | ||||
|   summary: Angular, React, VueJS, Webpack, etc. | ||||
| --- | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| 
 | ||||
| # Frameworks and Bundlers | ||||
| 
 | ||||
| import Tabs from '@theme/Tabs'; | ||||
| import TabItem from '@theme/TabItem'; | ||||
| 
 | ||||
| Each standalone release package is available at <https://cdn.sheetjs.com/>.  The | ||||
| NodeJS package is designed to be used with frameworks and bundlers.  It is a | ||||
| proper ECMAScript Module release which can be optimized with developer tools. | ||||
| 
 | ||||
| <Tabs> | ||||
|   <TabItem value="npm" label="npm"> | ||||
| <pre><code parentName="pre" {...{"className": "language-bash"}}>{`\ | ||||
| $ npm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| </code></pre> | ||||
|   </TabItem> | ||||
|   <TabItem value="pnpm" label="pnpm"> | ||||
| <pre><code parentName="pre" {...{"className": "language-bash"}}>{`\ | ||||
| $ pnpm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| </code></pre> | ||||
|   </TabItem> | ||||
|   <TabItem value="yarn" label="Yarn" default> | ||||
| <pre><code parentName="pre" {...{"className": "language-bash"}}>{`\ | ||||
| $ yarn add --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| </code></pre> | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
| 
 | ||||
| Once installed, the library can be imported under the name `xlsx`: | ||||
| 
 | ||||
| ```js | ||||
| import { read, writeFileXLSX } from "xlsx"; | ||||
| ``` | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>XLS Codepage support</b> (click to show)</summary> | ||||
| 
 | ||||
| If XLS support is required, `cpexcel.full.js` must be manually imported: | ||||
| 
 | ||||
| ```js | ||||
| /* load the codepage support library for extended support with older formats  */ | ||||
| import { set_cptable } from "xlsx"; | ||||
| import * as cptable from 'xlsx/dist/cpexcel.full.mjs'; | ||||
| set_cptable(cptable); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
							
								
								
									
										31
									
								
								docz/docs/02-installation/03-deno.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,31 @@ | ||||
| --- | ||||
| sidebar_position: 3 | ||||
| sidebar_custom_props: | ||||
|   summary: Import ECMAScript Modules and TypeScript definitions | ||||
| --- | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| 
 | ||||
| # Deno | ||||
| 
 | ||||
| Each standalone release script is available at <https://cdn.sheetjs.com/>. | ||||
| 
 | ||||
| Using the URL imports, `deno run` will automatically download scripts and types: | ||||
| 
 | ||||
| <pre><code parentName="pre" {...{"className": "language-ts"}}>{`\ | ||||
| // @deno-types="https://cdn.sheetjs.com/xlsx-${current}/package/types/index.d.ts" | ||||
| import * as XLSX from 'https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs';`} | ||||
| </code></pre> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>XLS Codepage support</b> (click to show)</summary> | ||||
| 
 | ||||
| If XLS support is required, `cpexcel.full.js` must be manually imported: | ||||
| 
 | ||||
| <pre><code parentName="pre" {...{"className": "language-ts"}}>{`\ | ||||
| /* load the codepage support library for extended support with older formats  */ | ||||
| import * as cptable from 'https://cdn.sheetjs.com/xlsx-${current}/package/dist/cpexcel.full.mjs'; | ||||
| XLSX.set_cptable(cptable);`} | ||||
| </code></pre> | ||||
| 
 | ||||
| </details> | ||||
							
								
								
									
										104
									
								
								docz/docs/02-installation/04-nodejs.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,104 @@ | ||||
| --- | ||||
| sidebar_position: 4 | ||||
| sidebar_custom_props: | ||||
|   summary: Server-side and other frameworks using NodeJS modules | ||||
| --- | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| 
 | ||||
| # NodeJS | ||||
| 
 | ||||
| import Tabs from '@theme/Tabs'; | ||||
| import TabItem from '@theme/TabItem'; | ||||
| 
 | ||||
| Tarballs are available on <https://cdn.sheetjs.com>. | ||||
| 
 | ||||
| <div>Each individual version can be referenced using a similar URL pattern. | ||||
| 
 | ||||
| <a href={`https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}>https://cdn.sheetjs.com/xlsx-{current}/xlsx-{current}.tgz</a> is the URL for {current}</div> | ||||
| 
 | ||||
| <https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz> is a link to the latest | ||||
| version and will refresh on each release. | ||||
| 
 | ||||
| ## Installation | ||||
| 
 | ||||
| Tarballs can be directly installed using a package manager: | ||||
| 
 | ||||
| <Tabs> | ||||
|   <TabItem value="npm" label="npm"> | ||||
| <pre><code parentName="pre" {...{"className": "language-bash"}}>{`\ | ||||
| $ npm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| </code></pre> | ||||
|   </TabItem> | ||||
|   <TabItem value="pnpm" label="pnpm"> | ||||
| <pre><code parentName="pre" {...{"className": "language-bash"}}>{`\ | ||||
| $ pnpm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| </code></pre> | ||||
|   </TabItem> | ||||
|   <TabItem value="yarn" label="Yarn" default> | ||||
| <pre><code parentName="pre" {...{"className": "language-bash"}}>{`\ | ||||
| $ yarn add --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| </code></pre> | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
| 
 | ||||
| ### Vendoring | ||||
| 
 | ||||
| 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. | ||||
| 
 | ||||
| 3) Install the tarball using a package manager: | ||||
| 
 | ||||
| <Tabs> | ||||
|   <TabItem value="npm" label="npm"> | ||||
| <pre><code parentName="pre" {...{"className": "language-bash"}}>{`\ | ||||
| $ npm install --save file:vendor/xlsx-${current}.tgz`} | ||||
| </code></pre> | ||||
|   </TabItem> | ||||
|   <TabItem value="pnpm" label="pnpm"> | ||||
| <pre><code parentName="pre" {...{"className": "language-bash"}}>{`\ | ||||
| $ pnpm install --save file:vendor/xlsx-${current}.tgz`} | ||||
| </code></pre> | ||||
|   </TabItem> | ||||
|   <TabItem value="yarn" label="Yarn" default> | ||||
| <pre><code parentName="pre" {...{"className": "language-bash"}}>{`\ | ||||
| $ yarn add --save file:vendor/xlsx-0.18.7.tgz`} | ||||
| </code></pre> | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
| 
 | ||||
| The package will be installed and accessible as `xlsx`. | ||||
| 
 | ||||
| ## Usage | ||||
| 
 | ||||
| By default, the module supports `require` and it will automatically add support | ||||
| for streams and filesystem access: | ||||
| 
 | ||||
| ```js | ||||
| var XLSX = require("xlsx"); | ||||
| ``` | ||||
| 
 | ||||
| The module also ships with `xlsx.mjs` for use with `import`.  The `mjs` version | ||||
| does not automatically load native node modules, so they must be added manually: | ||||
| 
 | ||||
| ```js | ||||
| import * as XLSX from 'xlsx/xlsx.mjs'; | ||||
| 
 | ||||
| /* load 'fs' for readFile and writeFile support */ | ||||
| import * as fs from 'fs'; | ||||
| XLSX.set_fs(fs); | ||||
| 
 | ||||
| /* load 'stream' for stream support */ | ||||
| import { Readable } from 'stream'; | ||||
| XLSX.stream.set_readable(Readable); | ||||
| 
 | ||||
| /* load the codepage support library for extended support with older formats  */ | ||||
| import * as cpexcel from 'xlsx/dist/cpexcel.full.mjs'; | ||||
| XLSX.set_cptable(cpexcel); | ||||
| ``` | ||||
| 
 | ||||
							
								
								
									
										21
									
								
								docz/docs/02-installation/05-extendscript.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,21 @@ | ||||
| --- | ||||
| sidebar_position: 5 | ||||
| sidebar_custom_props: | ||||
|   summary: Photoshop, InDesign, and other Creative Cloud apps | ||||
| --- | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| 
 | ||||
| # ExtendScript | ||||
| 
 | ||||
| Each standalone release script is available at <https://cdn.sheetjs.com/>. | ||||
| 
 | ||||
| `xlsx.extendscript.js` is an ExtendScript build for Photoshop and InDesign. | ||||
| 
 | ||||
| <div><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.extendscript.js`}>https://cdn.sheetjs.com/xlsx-{current}/package/dist/xlsx.extendscript.js</a> is the URL for {current}</div><br/> | ||||
| 
 | ||||
| After downloading the script, it can be directly referenced with `#include`: | ||||
| 
 | ||||
| ```c | ||||
| #include "xlsx.extendscript.js" | ||||
| ``` | ||||
							
								
								
									
										4
									
								
								docz/docs/02-installation/_category_.json
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,4 @@ | ||||
| { | ||||
|   "label": "Installation", | ||||
|   "position": 2 | ||||
| } | ||||
							
								
								
									
										20
									
								
								docz/docs/02-installation/index.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,20 @@ | ||||
| --- | ||||
| hide_table_of_contents: true | ||||
| --- | ||||
| 
 | ||||
| # Installation | ||||
| 
 | ||||
| import DocCardList from '@theme/DocCardList'; | ||||
| import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; | ||||
| 
 | ||||
| <https://cdn.sheetjs.com> is the primary software distribution site.  Please | ||||
| read the installation instructions for your use case: | ||||
| 
 | ||||
| <ul>{useCurrentSidebarCategory().items.map((item, index) => { | ||||
|   const listyle = (item.customProps?.icon) ? { | ||||
|     listStyleImage: `url("${item.customProps.icon}")` | ||||
|   } : {}; | ||||
|   return (<li style={listyle} {...(item.customProps?.class ? {className: item.customProps.class}: {})}> | ||||
|     <a href={item.href}>{item.label}</a>{item.customProps?.summary && (" - " + item.customProps.summary)} | ||||
|   </li>); | ||||
| })}</ul> | ||||
							
								
								
									
										375
									
								
								docz/docs/03-example.mdx
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,375 @@ | ||||
| --- | ||||
| sidebar_position: 3 | ||||
| --- | ||||
| 
 | ||||
| # Complete Example | ||||
| 
 | ||||
| SheetJS presents a simple JS interface that works with "Array of Arrays" and | ||||
| "Array of JS Objects".  The API functions are building blocks that should be | ||||
| combined with other JS APIs to solve problems. | ||||
| 
 | ||||
| The discussion focuses on the problem solving mindset.  API details are covered | ||||
| in other parts of the documentation. | ||||
| 
 | ||||
| The goal of this example is to generate a XLSB workbook of US President names | ||||
| and birthdays.  [Click here](#live-demo) to jump to the live demo | ||||
| 
 | ||||
| ## Acquire Data | ||||
| 
 | ||||
| ### Raw Data | ||||
| 
 | ||||
| [The raw data is available in JSON form](https://theunitedstates.io/congress-legislators/executive.json). | ||||
| For convenience, it has been [mirrored here](https://sheetjs.com/executive.json) | ||||
| 
 | ||||
| The data result is an Array of objects.  This is the data for John Adams: | ||||
| 
 | ||||
| ```js | ||||
| { | ||||
|   "id": { /* (data omitted) */ }, | ||||
|   "name": { | ||||
|     "first": "John",          // <-- first name | ||||
|     "last": "Adams"           // <-- last name | ||||
|   }, | ||||
|   "bio": { | ||||
|     "birthday": "1735-10-19", // <-- birthday | ||||
|     "gender": "M" | ||||
|   }, | ||||
|   "terms": [ | ||||
|     { "type": "viceprez", /* (other fields omitted) */ }, | ||||
|     { "type": "viceprez", /* (other fields omitted) */ }, | ||||
|     { "type": "prez", /* (other fields omitted) */ } | ||||
|   ] | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| ### Filtering for Presidents | ||||
| 
 | ||||
| The dataset includes Aaron Burr, a Vice President who was never President! | ||||
| 
 | ||||
| `Array#filter` creates a new array with the desired rows.  A President served | ||||
| at least one term with `type` set to `"prez"`.  To test if a particular row has | ||||
| at least one `"prez"` term, `Array#some` is another native JS function.  The | ||||
| complete filter would be: | ||||
| 
 | ||||
| ```js | ||||
| 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.bio.birthday`.  Using `Array#map`, the dataset can be massaged in one call: | ||||
| 
 | ||||
| ```js | ||||
| const rows = prez.map(row => ({ | ||||
|   name: row.name.first + " " + row.name.last, | ||||
|   birthday: row.bio.birthday | ||||
| })); | ||||
| ``` | ||||
| 
 | ||||
| The result is an array of "simple" objects with no nesting: | ||||
| 
 | ||||
| ```js | ||||
| [ | ||||
|   { name: "George Washington", birthday: "1732-02-22" }, | ||||
|   { name: "John Adams", birthday: "1735-10-19" }, | ||||
|   // ... one row per President | ||||
| ] | ||||
| ``` | ||||
| 
 | ||||
| ## Create a Workbook | ||||
| 
 | ||||
| With the cleaned dataset, `XLSX.utils.json_to_sheet` generates a worksheet: | ||||
| 
 | ||||
| ```js | ||||
| const worksheet = XLSX.utils.json_to_sheet(rows); | ||||
| ``` | ||||
| 
 | ||||
| `XLSX.utils.book_new` creates a new workbook and `XLSX.utils.book_append_sheet` | ||||
| appends a worksheet to the workbook. The new worksheet will be called "Dates": | ||||
| 
 | ||||
| ```js | ||||
| const workbook = XLSX.utils.book_new(); | ||||
| XLSX.utils.book_append_sheet(workbook, worksheet, "Dates"); | ||||
| ``` | ||||
| 
 | ||||
| ## Clean up Workbook | ||||
| 
 | ||||
| The data is in the workbook and can be exported. | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| There are multiple opportunities for improvement: the headers can be renamed and | ||||
| the column widths can be adjusted.  [SheetJS Pro](https://sheetjs.com/pro) offers | ||||
| additional styling options like cell styling and frozen rows. | ||||
| 
 | ||||
| <details><summary><b>Changing Header Names</b> (click to show)</summary> | ||||
| 
 | ||||
| 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: | ||||
| 
 | ||||
| ```js | ||||
| XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details><summary><b>Changing Column Widths</b> (click to show)</summary> | ||||
| 
 | ||||
| Some of the names are longer than the default column width.  Column widths are | ||||
| set by setting the `"!cols"` worksheet property. | ||||
| 
 | ||||
| The following line sets the width of column A to approximately 10 characters: | ||||
| 
 | ||||
| ```js | ||||
| worksheet["!cols"] = [ { wch: 10 } ]; // set column A width to 10 characters | ||||
| ``` | ||||
| 
 | ||||
| One `Array#reduce` call over `rows` can calculate the maximum width: | ||||
| 
 | ||||
| ```js | ||||
| const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); | ||||
| worksheet["!cols"] = [ { wch: max_width } ]; | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ## Export a File | ||||
| 
 | ||||
| `XLSX.writeFile` creates a spreadsheet file and tries to write it to the system. | ||||
| In the browser, it will try to prompt the user to download the file.  In NodeJS, | ||||
| it will write to the local directory. | ||||
| 
 | ||||
| ```js | ||||
| XLSX.writeFile(workbook, "Presidents.xlsb"); | ||||
| ``` | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| 
 | ||||
| ## Live Demo | ||||
| 
 | ||||
| ```jsx live | ||||
| function Presidents() { return ( <button onClick={async () => { | ||||
|   /* fetch JSON data and parse */ | ||||
|   const url = "https://sheetjs.com/executive.json"; | ||||
|   const raw_data = await (await fetch(url)).json(); | ||||
| 
 | ||||
|   /* filter for the Presidents */ | ||||
|   const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); | ||||
| 
 | ||||
|   /* flatten objects */ | ||||
|   const rows = prez.map(row => ({ | ||||
|     name: row.name.first + " " + row.name.last, | ||||
|     birthday: row.bio.birthday | ||||
|   })); | ||||
| 
 | ||||
|   /* generate worksheet and workbook */ | ||||
|   const worksheet = XLSX.utils.json_to_sheet(rows); | ||||
|   const workbook = XLSX.utils.book_new(); | ||||
|   XLSX.utils.book_append_sheet(workbook, worksheet, "Dates"); | ||||
| 
 | ||||
|   /* fix headers */ | ||||
|   XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); | ||||
| 
 | ||||
|   /* calculate column width */ | ||||
|   const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); | ||||
|   worksheet["!cols"] = [ { wch: max_width } ]; | ||||
| 
 | ||||
|   /* create an XLSX file and try to save to Presidents.xlsb */ | ||||
|   XLSX.writeFile(workbook, "Presidents.xlsb"); | ||||
| }}><b>Click to Generate file!</b></button> ); } | ||||
| ``` | ||||
| 
 | ||||
| ## Run the Demo Locally | ||||
| 
 | ||||
| import Tabs from '@theme/Tabs'; | ||||
| import TabItem from '@theme/TabItem'; | ||||
| 
 | ||||
| <Tabs> | ||||
|   <TabItem value="browser" label="Browser"> | ||||
| 
 | ||||
| Save the following script to `snippet.html` and open the page.  The page must be | ||||
| hosted (no `file:///` access). | ||||
| 
 | ||||
| <https://sheetjs.com/pres.html> is a hosted version of the page. | ||||
| 
 | ||||
| ```html | ||||
| <body> | ||||
| <script src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"></script> | ||||
| <script> | ||||
| (async() => { | ||||
|   /* fetch JSON data and parse */ | ||||
|   const url = "https://sheetjs.com/executive.json"; | ||||
|   const raw_data = await (await fetch(url)).json(); | ||||
| 
 | ||||
|   /* filter for the Presidents */ | ||||
|   const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); | ||||
| 
 | ||||
|   /* flatten objects */ | ||||
|   const rows = prez.map(row => ({ | ||||
|     name: row.name.first + " " + row.name.last, | ||||
|     birthday: row.bio.birthday | ||||
|   })); | ||||
| 
 | ||||
|   /* generate worksheet and workbook */ | ||||
|   const worksheet = XLSX.utils.json_to_sheet(rows); | ||||
|   const workbook = XLSX.utils.book_new(); | ||||
|   XLSX.utils.book_append_sheet(workbook, worksheet, "Dates"); | ||||
| 
 | ||||
|   /* fix headers */ | ||||
|   XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); | ||||
| 
 | ||||
|   /* calculate column width */ | ||||
|   const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); | ||||
|   worksheet["!cols"] = [ { wch: max_width } ]; | ||||
| 
 | ||||
|   /* create an XLSX file and try to save to Presidents.xlsb */ | ||||
|   XLSX.writeFile(workbook, "Presidents.xlsb"); | ||||
| })(); | ||||
| </script> | ||||
| <body> | ||||
| ``` | ||||
|   </TabItem> | ||||
|   <TabItem value="nodejs" label="NodeJS"> | ||||
| 
 | ||||
| Install the dependencies: | ||||
| 
 | ||||
| ```bash | ||||
| $ npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz | ||||
| ``` | ||||
| 
 | ||||
| Save the following script to `snippet.js` and run `node snippet.js`: | ||||
| 
 | ||||
| ```js | ||||
| const XLSX = require("xlsx"); | ||||
| 
 | ||||
| (async() => { | ||||
|   /* fetch JSON data and parse */ | ||||
|   const url = "https://sheetjs.com/executive.json"; | ||||
|   const raw_data = await (await fetch(url)).json(); | ||||
| 
 | ||||
|   /* filter for the Presidents */ | ||||
|   const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); | ||||
| 
 | ||||
|   /* flatten objects */ | ||||
|   const rows = prez.map(row => ({ | ||||
|     name: row.name.first + " " + row.name.last, | ||||
|     birthday: row.bio.birthday | ||||
|   })); | ||||
| 
 | ||||
|   /* generate worksheet and workbook */ | ||||
|   const worksheet = XLSX.utils.json_to_sheet(rows); | ||||
|   const workbook = XLSX.utils.book_new(); | ||||
|   XLSX.utils.book_append_sheet(workbook, worksheet, "Dates"); | ||||
| 
 | ||||
|   /* fix headers */ | ||||
|   XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); | ||||
| 
 | ||||
|   /* calculate column width */ | ||||
|   const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); | ||||
|   worksheet["!cols"] = [ { wch: max_width } ]; | ||||
| 
 | ||||
|   /* create an XLSX file and try to save to Presidents.xlsb */ | ||||
|   XLSX.writeFile(workbook, "Presidents.xlsb"); | ||||
| })(); | ||||
| ``` | ||||
| 
 | ||||
| Native `fetch` support was added in NodeJS 18.  For older versions of NodeJS, | ||||
| the script will throw an error `fetch is not defined`.  A third-party library | ||||
| like `axios` presents a similar API for fetching data: | ||||
| 
 | ||||
| <details><summary><b>Example using axios</b> (click to show)</summary> | ||||
| 
 | ||||
| Install the dependencies: | ||||
| 
 | ||||
| ```bash | ||||
| $ npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz | ||||
| ``` | ||||
| 
 | ||||
| The differences in the script are highlighted below. | ||||
| 
 | ||||
| ```js | ||||
| const XLSX = require("xlsx"); | ||||
| // highlight-next-line | ||||
| const axios = require("axios"); | ||||
| 
 | ||||
| (async() => { | ||||
|   /* fetch JSON data and parse */ | ||||
|   const url = "https://sheetjs.com/executive.json"; | ||||
|   // highlight-next-line | ||||
|   const raw_data = (await axios(url, {responseType: "json"})).data; | ||||
| 
 | ||||
|   /* filter for the Presidents */ | ||||
|   const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); | ||||
| 
 | ||||
|   /* flatten objects */ | ||||
|   const rows = prez.map(row => ({ | ||||
|     name: row.name.first + " " + row.name.last, | ||||
|     birthday: row.bio.birthday | ||||
|   })); | ||||
| 
 | ||||
|   /* generate worksheet and workbook */ | ||||
|   const worksheet = XLSX.utils.json_to_sheet(rows); | ||||
|   const workbook = XLSX.utils.book_new(); | ||||
|   XLSX.utils.book_append_sheet(workbook, worksheet, "Dates"); | ||||
| 
 | ||||
|   /* fix headers */ | ||||
|   XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); | ||||
| 
 | ||||
|   /* calculate column width */ | ||||
|   const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); | ||||
|   worksheet["!cols"] = [ { wch: max_width } ]; | ||||
| 
 | ||||
|   /* create an XLSX file and try to save to Presidents.xlsb */ | ||||
|   XLSX.writeFile(workbook, "Presidents.xlsb"); | ||||
| })(); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
|   </TabItem> | ||||
|   <TabItem value="deno" label="Deno"> | ||||
| 
 | ||||
| Save the following script to `snippet.ts` and run with | ||||
| `deno run --allow-net --allow-write snippet.ts`: | ||||
| 
 | ||||
| ```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'; | ||||
| 
 | ||||
| /* fetch JSON data and parse */ | ||||
| const url = "https://sheetjs.com/executive.json"; | ||||
| const raw_data = await (await fetch(url)).json(); | ||||
| 
 | ||||
| /* filter for the Presidents */ | ||||
| const prez = raw_data.filter((row: any) => row.terms.some((term: any) => term.type === "prez")); | ||||
| 
 | ||||
| /* flatten objects */ | ||||
| const rows = prez.map((row: any) => ({ | ||||
|   name: row.name.first + " " + row.name.last, | ||||
|   birthday: row.bio.birthday | ||||
| })); | ||||
| 
 | ||||
| /* generate worksheet and workbook */ | ||||
| const worksheet = XLSX.utils.json_to_sheet(rows); | ||||
| const workbook = XLSX.utils.book_new(); | ||||
| XLSX.utils.book_append_sheet(workbook, worksheet, "Dates"); | ||||
| 
 | ||||
| /* fix headers */ | ||||
| XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); | ||||
| 
 | ||||
| /* calculate column width */ | ||||
| const max_width = rows.reduce((w: number, r: any) => Math.max(w, r.name.length), 10); | ||||
| worksheet["!cols"] = [ { wch: max_width } ]; | ||||
| 
 | ||||
| /* create an XLSX file and try to save to Presidents.xlsb */ | ||||
| XLSX.writeFile(workbook, "Presidents.xlsb"); | ||||
| ``` | ||||
| 
 | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
							
								
								
									
										67
									
								
								docz/docs/04-getting-started/01-roadmap.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,67 @@ | ||||
| --- | ||||
| sidebar_position: 1 | ||||
| --- | ||||
| 
 | ||||
| # Roadmap | ||||
| 
 | ||||
| Most scenarios involving spreadsheets and data can be divided into 5 parts: | ||||
| 
 | ||||
| 1) **Acquire Data**:  Data may be stored anywhere: local or remote files, | ||||
|    databases, HTML TABLE, or even generated programmatically in the web browser. | ||||
| 
 | ||||
| 2) **Extract Data**:  For spreadsheet files, this involves parsing raw bytes to | ||||
|    read the cell data. For general JS data, this involves reshaping the data. | ||||
| 
 | ||||
| 3) **Process Data**:  From generating summary statistics to cleaning data | ||||
|    records, this step is the heart of the problem. | ||||
| 
 | ||||
| 4) **Package Data**:  This can involve making a new spreadsheet or serializing | ||||
|    with `JSON.stringify` or writing XML or simply flattening data for UI tools. | ||||
| 
 | ||||
| 5) **Release Data**:  Spreadsheet files can be uploaded to a server or written | ||||
|    locally.  Data can be presented to users in an HTML TABLE or data grid. | ||||
| 
 | ||||
| A common problem involves generating a valid spreadsheet export from data stored | ||||
| in an HTML table.  In this example, an HTML TABLE on the page will be scraped, | ||||
| a row will be added to the bottom with the date of the report, and a new file | ||||
| will be generated and downloaded locally. `XLSX.writeFile` takes care of | ||||
| packaging the data and attempting a local download: | ||||
| 
 | ||||
| ```js | ||||
| // Acquire Data (reference to the HTML table) | ||||
| var table_elt = document.getElementById("my-table-id"); | ||||
| 
 | ||||
| // Extract Data (create a workbook object from the table) | ||||
| var workbook = XLSX.utils.table_to_book(table_elt); | ||||
| 
 | ||||
| // Process Data (add a new row) | ||||
| var ws = workbook.Sheets["Sheet1"]; | ||||
| XLSX.utils.sheet_add_aoa(ws, [["Created "+new Date().toISOString()]], {origin:-1}); | ||||
| 
 | ||||
| // Package and Release Data (`writeFile` tries to write and save an XLSB file) | ||||
| XLSX.writeFile(workbook, "Report.xlsb"); | ||||
| ``` | ||||
| 
 | ||||
| This library tries to simplify steps 2 and 4 with functions to extract useful | ||||
| data from spreadsheet files (`read` / `readFile`) and generate new spreadsheet | ||||
| files from data (`write` / `writeFile`).  Additional utility functions like | ||||
| `table_to_book` work with other common data sources like HTML tables. | ||||
| 
 | ||||
| This documentation and various demo projects cover a number of common scenarios | ||||
| and approaches for steps 1 and 5. | ||||
| 
 | ||||
| Utility functions help with step 3. | ||||
| 
 | ||||
| ## Highlights | ||||
| 
 | ||||
| ["Data Import"](../solutions/input) describes solutions for common data import | ||||
| scenarios. | ||||
| 
 | ||||
| ["Data Export"](../solutions/output) describes solutions for common data export | ||||
| scenarios. | ||||
| 
 | ||||
| ["Data Processing"](../solutions/processing) describes solutions for common | ||||
| workbook processing and manipulation scenarios. | ||||
| 
 | ||||
| ["Utility Functions"](../api/utilities) details utility functions for | ||||
| translating JSON Arrays and other common JS structures into worksheet objects. | ||||
							
								
								
									
										37
									
								
								docz/docs/04-getting-started/02-zen.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,37 @@ | ||||
| --- | ||||
| sidebar_position: 2 | ||||
| hide_table_of_contents: true | ||||
| --- | ||||
| 
 | ||||
| # Zen of SheetJS | ||||
| 
 | ||||
| SheetJS design and development is guided by a few key principles. | ||||
| 
 | ||||
| ### Data processing should fit in any workflow | ||||
| 
 | ||||
| The library does not impose a separate lifecycle.  It fits nicely in websites | ||||
| and apps built using any framework.  The plain JS data objects play nice with | ||||
| Web Workers and future APIs. | ||||
| 
 | ||||
| ### JavaScript is a powerful language for data processing | ||||
| 
 | ||||
| The ["Common Spreadsheet Format"](../csf/general) is a simple object | ||||
| representation of the core concepts of a workbook.  The various functions in the | ||||
| library provide low-level tools for working with the object. | ||||
| 
 | ||||
| For friendly JS processing, there are utility functions for converting parts of | ||||
| a worksheet to/from an Array of Arrays.  The [Complete example](../03-example.mdx) | ||||
| combines powerful JS Array methods with a network request library to download | ||||
| data, select the information we want and create a workbook file: | ||||
| 
 | ||||
| ### File formats are implementation details | ||||
| 
 | ||||
| The parser covers a wide gamut of common spreadsheet file formats to ensure that | ||||
| "HTML-saved-as-XLS" files work as well as actual XLS or XLSX files. | ||||
| 
 | ||||
| The writer supports a number of common output formats for broad compatibility | ||||
| with the data ecosystem. | ||||
| 
 | ||||
| To the greatest extent possible, data processing code should not have to worry | ||||
| about the specific file formats involved. | ||||
| 
 | ||||
							
								
								
									
										50
									
								
								docz/docs/04-getting-started/03-demos.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,50 @@ | ||||
| --- | ||||
| sidebar_position: 3 | ||||
| hide_table_of_contents: true | ||||
| --- | ||||
| 
 | ||||
| # Demo Projects | ||||
| 
 | ||||
| The demo projects include small runnable examples and short explainers. | ||||
| 
 | ||||
| ### Frameworks and APIs | ||||
| 
 | ||||
| - [`Angular.JS`](https://github.com/SheetJS/SheetJS/tree/master/demos/angular/) | ||||
| - [`Angular 2+ and Ionic`](https://github.com/SheetJS/SheetJS/tree/master/demos/angular2/) | ||||
| - [`Knockout`](https://github.com/SheetJS/SheetJS/tree/master/demos/knockout/) | ||||
| - [`Meteor`](https://github.com/SheetJS/SheetJS/tree/master/demos/meteor/) | ||||
| - [`React, React Native and NextJS`](https://github.com/SheetJS/SheetJS/tree/master/demos/react/) | ||||
| - [`VueJS, WeeX, and NuxtJS`](https://github.com/SheetJS/SheetJS/tree/master/demos/vue/) | ||||
| - [`XMLHttpRequest and fetch`](https://github.com/SheetJS/SheetJS/tree/master/demos/xhr/) | ||||
| - [`NodeJS Server-Side Processing`](https://github.com/SheetJS/SheetJS/tree/master/demos/server/) | ||||
| - [`Databases and Key/Value Stores`](https://github.com/SheetJS/SheetJS/tree/master/demos/database/) | ||||
| - [`Typed Arrays and Math`](https://github.com/SheetJS/SheetJS/tree/master/demos/array/) | ||||
| 
 | ||||
| ### Front-End UI Components | ||||
| 
 | ||||
| - [`canvas-datagrid`](https://github.com/SheetJS/SheetJS/tree/master/demos/datagrid/) | ||||
| - [`x-spreadsheet`](https://github.com/SheetJS/SheetJS/tree/master/demos/xspreadsheet/) | ||||
| - [`react-data-grid`](https://github.com/SheetJS/SheetJS/tree/master/demos/react/modify/) | ||||
| - [`vue3-table-light`](https://github.com/SheetJS/SheetJS/tree/master/demos/vue/modify/) | ||||
| 
 | ||||
| ### Platforms and Integrations | ||||
| - [`Deno`](https://github.com/SheetJS/SheetJS/tree/master/demos/deno/) | ||||
| - [`Electron`](https://github.com/SheetJS/SheetJS/tree/master/demos/electron/) | ||||
| - [`NW.js`](https://github.com/SheetJS/SheetJS/tree/master/demos/nwjs/) | ||||
| - [`Chrome / Chromium Extension`](https://github.com/SheetJS/SheetJS/tree/master/demos/chrome/) | ||||
| - [`Google Sheet export`](https://github.com/SheetJS/SheetJS/tree/master/demos/google-sheet/) | ||||
| - [`ExtendScript for Adobe Apps`](https://github.com/SheetJS/SheetJS/tree/master/demos/extendscript/) | ||||
| - [`Headless Browsers`](https://github.com/SheetJS/SheetJS/tree/master/demos/headless/) | ||||
| - [`Other JavaScript Engines`](https://github.com/SheetJS/SheetJS/tree/master/demos/altjs/) | ||||
| - [`"serverless" functions`](https://github.com/SheetJS/SheetJS/tree/master/demos/function/) | ||||
| - [`Legacy Internet Explorer`](https://github.com/SheetJS/SheetJS/tree/master/demos/oldie/) | ||||
| 
 | ||||
| ### Bundlers and Tooling | ||||
| - [`browserify`](https://github.com/SheetJS/SheetJS/tree/master/demos/browserify/) | ||||
| - [`fusebox`](https://github.com/SheetJS/SheetJS/tree/master/demos/fusebox/) | ||||
| - [`parcel`](https://github.com/SheetJS/SheetJS/tree/master/demos/parcel/) | ||||
| - [`requirejs`](https://github.com/SheetJS/SheetJS/tree/master/demos/requirejs/) | ||||
| - [`rollup`](https://github.com/SheetJS/SheetJS/tree/master/demos/rollup/) | ||||
| - [`systemjs`](https://github.com/SheetJS/SheetJS/tree/master/demos/systemjs/) | ||||
| - [`typescript`](https://github.com/SheetJS/SheetJS/tree/master/demos/typescript/) | ||||
| - [`webpack 2.x`](https://github.com/SheetJS/SheetJS/tree/master/demos/webpack/) | ||||
							
								
								
									
										4
									
								
								docz/docs/04-getting-started/_category_.json
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,4 @@ | ||||
| { | ||||
|   "label": "Getting Started", | ||||
|   "position": 4 | ||||
| } | ||||
							
								
								
									
										
											BIN
										
									
								
								docz/docs/04-getting-started/img/docsVersionDropdown.png
									
									
									
									
									
										Normal file
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						| After Width: | Height: | Size: 25 KiB | 
							
								
								
									
										
											BIN
										
									
								
								docz/docs/04-getting-started/img/localeDropdown.png
									
									
									
									
									
										Normal file
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						| After Width: | Height: | Size: 27 KiB | 
							
								
								
									
										70
									
								
								docz/docs/05-interface.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,70 @@ | ||||
| --- | ||||
| sidebar_position: 5 | ||||
| --- | ||||
| 
 | ||||
| # Interface Summary | ||||
| 
 | ||||
| `XLSX` is the exposed variable in the browser and the exported node variable | ||||
| 
 | ||||
| `XLSX.version` is the version of the library (added by the build script). | ||||
| 
 | ||||
| `XLSX.SSF` is an embedded version of the [format library](https://github.com/SheetJS/ssf). | ||||
| 
 | ||||
| ## Parsing functions | ||||
| 
 | ||||
| `XLSX.read(data, read_opts)` attempts to parse `data`. | ||||
| 
 | ||||
| `XLSX.readFile(filename, read_opts)` attempts to read `filename` and parse. | ||||
| 
 | ||||
| Parse options are described in the [Parsing Options](./api/parse-options) section. | ||||
| 
 | ||||
| ## Writing functions | ||||
| 
 | ||||
| `XLSX.write(wb, write_opts)` attempts to write the workbook `wb` | ||||
| 
 | ||||
| `XLSX.writeFile(wb, filename, write_opts)` attempts to write `wb` to `filename`. | ||||
| In browser-based environments, it will attempt to force a client-side download. | ||||
| 
 | ||||
| `XLSX.writeFileAsync(filename, wb, o, cb)` attempts to write `wb` to `filename`. | ||||
| If `o` is omitted, the writer will use the third argument as the callback. | ||||
| 
 | ||||
| `XLSX.stream` contains a set of streaming write functions. | ||||
| 
 | ||||
| Write options are described in the [Writing Options](./api/write-options) section. | ||||
| 
 | ||||
| ## Utilities | ||||
| 
 | ||||
| Utilities are available in the `XLSX.utils` object and are described in the | ||||
| [Utility Functions](./api/utilities) section: | ||||
| 
 | ||||
| **Constructing:** | ||||
| 
 | ||||
| - `book_new` creates an empty workbook | ||||
| - `book_append_sheet` adds a worksheet to a workbook | ||||
| 
 | ||||
| **Importing:** | ||||
| 
 | ||||
| - `aoa_to_sheet` converts an array of arrays of JS data to a worksheet. | ||||
| - `json_to_sheet` converts an array of JS objects to a worksheet. | ||||
| - `table_to_sheet` converts a DOM TABLE element to a worksheet. | ||||
| - `sheet_add_aoa` adds an array of arrays of JS data to an existing worksheet. | ||||
| - `sheet_add_json` adds an array of JS objects to an existing worksheet. | ||||
| 
 | ||||
| 
 | ||||
| **Exporting:** | ||||
| 
 | ||||
| - `sheet_to_json` converts a worksheet object to an array of JSON objects. | ||||
| - `sheet_to_csv` generates delimiter-separated-values output. | ||||
| - `sheet_to_txt` generates UTF16 formatted text. | ||||
| - `sheet_to_html` generates HTML output. | ||||
| - `sheet_to_formulae` generates a list of the formulae (with value fallbacks). | ||||
| 
 | ||||
| 
 | ||||
| **Cell and cell address manipulation:** | ||||
| 
 | ||||
| - `format_cell` generates the text value for a cell (using number formats). | ||||
| - `encode_row / decode_row` converts between 0-indexed rows and 1-indexed rows. | ||||
| - `encode_col / decode_col` converts between 0-indexed columns and column names. | ||||
| - `encode_cell / decode_cell` converts cell addresses. | ||||
| - `encode_range / decode_range` converts cell ranges. | ||||
| 
 | ||||
							
								
								
									
										782
									
								
								docz/docs/06-solutions/01-input.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,782 @@ | ||||
| --- | ||||
| sidebar_position: 1 | ||||
| --- | ||||
| 
 | ||||
| # Data Import | ||||
| 
 | ||||
| ## Parsing Workbooks | ||||
| 
 | ||||
| #### API | ||||
| 
 | ||||
| _Extract data from spreadsheet bytes_ | ||||
| 
 | ||||
| ```js | ||||
| var workbook = XLSX.read(data, opts); | ||||
| ``` | ||||
| 
 | ||||
| The `read` method can extract data from spreadsheet bytes stored in a JS string, | ||||
| "binary string", NodeJS buffer or typed array (`Uint8Array` or `ArrayBuffer`). | ||||
| 
 | ||||
| 
 | ||||
| _Read spreadsheet bytes from a local file and extract data_ | ||||
| 
 | ||||
| ```js | ||||
| var workbook = XLSX.readFile(filename, opts); | ||||
| ``` | ||||
| 
 | ||||
| The `readFile` method attempts to read a spreadsheet file at the supplied path. | ||||
| Browsers generally do not allow reading files in this way (it is deemed a | ||||
| security risk), and attempts to read files in this way will throw an error. | ||||
| 
 | ||||
| The second `opts` argument is optional. ["Parsing Options"](../api/parse-options) | ||||
| covers the supported properties and behaviors. | ||||
| 
 | ||||
| #### Examples | ||||
| 
 | ||||
| Here are a few common scenarios (click on each subtitle to see the code): | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Local file in a NodeJS server</b> (click to show)</summary> | ||||
| 
 | ||||
| `readFile` uses `fs.readFileSync` under the hood: | ||||
| 
 | ||||
| ```js | ||||
| var XLSX = require("xlsx"); | ||||
| 
 | ||||
| var workbook = XLSX.readFile("test.xlsx"); | ||||
| ``` | ||||
| 
 | ||||
| For Node ESM, the `readFile` helper is not enabled. Instead, `fs.readFileSync` | ||||
| should be used to read the file data as a `Buffer` for use with `XLSX.read`: | ||||
| 
 | ||||
| ```js | ||||
| import { readFileSync } from "fs"; | ||||
| import { read } from "xlsx/xlsx.mjs"; | ||||
| 
 | ||||
| const buf = readFileSync("test.xlsx"); | ||||
| /* buf is a Buffer */ | ||||
| const workbook = read(buf); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Local file in a Deno application</b> (click to show)</summary> | ||||
| 
 | ||||
| `readFile` uses `Deno.readFileSync` under the hood: | ||||
| 
 | ||||
| ```js | ||||
| // @deno-types="https://deno.land/x/sheetjs/types/index.d.ts" | ||||
| import * as XLSX from 'https://deno.land/x/sheetjs/xlsx.mjs' | ||||
| 
 | ||||
| const workbook = XLSX.readFile("test.xlsx"); | ||||
| ``` | ||||
| 
 | ||||
| Applications reading files must be invoked with the `--allow-read` flag.  The | ||||
| [`deno` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/deno/) has more examples | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>User-submitted file in a web page ("Drag-and-Drop")</b> (click to show)</summary> | ||||
| 
 | ||||
| For modern websites targeting Chrome 76+, `File#arrayBuffer` is recommended: | ||||
| 
 | ||||
| ```js | ||||
| // XLSX is a global from the standalone script | ||||
| 
 | ||||
| async function handleDropAsync(e) { | ||||
|   e.stopPropagation(); e.preventDefault(); | ||||
|   const f = e.dataTransfer.files[0]; | ||||
|   /* f is a File */ | ||||
|   const data = await f.arrayBuffer(); | ||||
|   /* data is an ArrayBuffer */ | ||||
|   const workbook = XLSX.read(data); | ||||
| 
 | ||||
|   /* DO SOMETHING WITH workbook HERE */ | ||||
| } | ||||
| drop_dom_element.addEventListener("drop", handleDropAsync, false); | ||||
| ``` | ||||
| 
 | ||||
| For maximal compatibility, the `FileReader` API should be used: | ||||
| 
 | ||||
| ```js | ||||
| function handleDrop(e) { | ||||
|   e.stopPropagation(); e.preventDefault(); | ||||
|   var f = e.dataTransfer.files[0]; | ||||
|   /* f is a File */ | ||||
|   var reader = new FileReader(); | ||||
|   reader.onload = function(e) { | ||||
|     var data = e.target.result; | ||||
|     /* reader.readAsArrayBuffer(file) -> data will be an ArrayBuffer */ | ||||
|     var workbook = XLSX.read(data); | ||||
| 
 | ||||
|     /* DO SOMETHING WITH workbook HERE */ | ||||
|   }; | ||||
|   reader.readAsArrayBuffer(f); | ||||
| } | ||||
| drop_dom_element.addEventListener("drop", handleDrop, false); | ||||
| ``` | ||||
| 
 | ||||
| <https://oss.sheetjs.com/sheetjs/> demonstrates the FileReader technique. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>User-submitted file with an HTML INPUT element</b> (click to show)</summary> | ||||
| 
 | ||||
| Starting with an HTML INPUT element with `type="file"`: | ||||
| 
 | ||||
| ```html | ||||
| <input type="file" id="input_dom_element"> | ||||
| ``` | ||||
| 
 | ||||
| For modern websites targeting Chrome 76+, `Blob#arrayBuffer` is recommended: | ||||
| 
 | ||||
| ```js | ||||
| // XLSX is a global from the standalone script | ||||
| 
 | ||||
| async function handleFileAsync(e) { | ||||
|   const file = e.target.files[0]; | ||||
|   const data = await file.arrayBuffer(); | ||||
|   /* data is an ArrayBuffer */ | ||||
|   const workbook = XLSX.read(data); | ||||
| 
 | ||||
|   /* DO SOMETHING WITH workbook HERE */ | ||||
| } | ||||
| input_dom_element.addEventListener("change", handleFileAsync, false); | ||||
| ``` | ||||
| 
 | ||||
| For broader support (including IE10+), the `FileReader` approach is recommended: | ||||
| 
 | ||||
| ```js | ||||
| function handleFile(e) { | ||||
|   var file = e.target.files[0]; | ||||
|   var reader = new FileReader(); | ||||
|   reader.onload = function(e) { | ||||
|     var data = e.target.result; | ||||
|     /* reader.readAsArrayBuffer(file) -> data will be an ArrayBuffer */ | ||||
|     var workbook = XLSX.read(e.target.result); | ||||
| 
 | ||||
|     /* DO SOMETHING WITH workbook HERE */ | ||||
|   }; | ||||
|   reader.readAsArrayBuffer(file); | ||||
| } | ||||
| input_dom_element.addEventListener("change", handleFile, false); | ||||
| ``` | ||||
| 
 | ||||
| The [`oldie` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/oldie/) shows an IE-compatible fallback scenario. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Fetching a file in the web browser ("Ajax")</b> (click to show)</summary> | ||||
| 
 | ||||
| For modern websites targeting Chrome 42+, `fetch` is recommended: | ||||
| 
 | ||||
| ```js | ||||
| // XLSX is a global from the standalone script | ||||
| 
 | ||||
| (async() => { | ||||
|   const url = "http://oss.sheetjs.com/test_files/formula_stress_test.xlsx"; | ||||
|   const data = await (await fetch(url)).arrayBuffer(); | ||||
|   /* data is an ArrayBuffer */ | ||||
|   const workbook = XLSX.read(data); | ||||
| 
 | ||||
|   /* DO SOMETHING WITH workbook HERE */ | ||||
| })(); | ||||
| ``` | ||||
| 
 | ||||
| For broader support, the `XMLHttpRequest` approach is recommended: | ||||
| 
 | ||||
| ```js | ||||
| var url = "http://oss.sheetjs.com/test_files/formula_stress_test.xlsx"; | ||||
| 
 | ||||
| /* set up async GET request */ | ||||
| var req = new XMLHttpRequest(); | ||||
| req.open("GET", url, true); | ||||
| req.responseType = "arraybuffer"; | ||||
| 
 | ||||
| req.onload = function(e) { | ||||
|   var workbook = XLSX.read(req.response); | ||||
| 
 | ||||
|   /* DO SOMETHING WITH workbook HERE */ | ||||
| }; | ||||
| 
 | ||||
| req.send(); | ||||
| ``` | ||||
| 
 | ||||
| The [`xhr` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/xhr/) includes a longer discussion and more examples. | ||||
| 
 | ||||
| <http://oss.sheetjs.com/sheetjs/ajax.html> shows fallback approaches for IE6+. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Local file in a PhotoShop or InDesign plugin</b> (click to show)</summary> | ||||
| 
 | ||||
| `readFile` wraps the `File` logic in Photoshop and other ExtendScript targets. | ||||
| The specified path should be an absolute path: | ||||
| 
 | ||||
| ```js | ||||
| #include "xlsx.extendscript.js" | ||||
| 
 | ||||
| /* Read test.xlsx from the Documents folder */ | ||||
| var workbook = XLSX.readFile(Folder.myDocuments + "/test.xlsx"); | ||||
| ``` | ||||
| 
 | ||||
| The [`extendscript` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/extendscript/) includes a more complex example. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Local file in an Electron app</b> (click to show)</summary> | ||||
| 
 | ||||
| `readFile` can be used in the renderer process: | ||||
| 
 | ||||
| ```js | ||||
| /* From the renderer process */ | ||||
| var XLSX = require("xlsx"); | ||||
| 
 | ||||
| var workbook = XLSX.readFile(path); | ||||
| ``` | ||||
| 
 | ||||
| Electron APIs have changed over time.  The [`electron` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/electron/) | ||||
| shows a complete example and details the required version-specific settings. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Local file in a mobile app with React Native</b> (click to show)</summary> | ||||
| 
 | ||||
| The [`react` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/react) includes a sample React Native app. | ||||
| 
 | ||||
| Since React Native does not provide a way to read files from the filesystem, a | ||||
| third-party library must be used.  The following libraries have been tested: | ||||
| 
 | ||||
| - [`react-native-file-access`](https://npm.im/react-native-file-access) | ||||
| 
 | ||||
| The `base64` encoding returns strings compatible with the `base64` type: | ||||
| 
 | ||||
| ```js | ||||
| import XLSX from "xlsx"; | ||||
| import { FileSystem } from "react-native-file-access"; | ||||
| 
 | ||||
| const b64 = await FileSystem.readFile(path, "base64"); | ||||
| /* b64 is a base64 string */ | ||||
| const workbook = XLSX.read(b64, {type: "base64"}); | ||||
| ``` | ||||
| 
 | ||||
| - [`react-native-fs`](https://npm.im/react-native-fs) | ||||
| 
 | ||||
| The `ascii` encoding returns binary strings compatible with the `binary` type: | ||||
| 
 | ||||
| ```js | ||||
| import XLSX from "xlsx"; | ||||
| import { readFile } from "react-native-fs"; | ||||
| 
 | ||||
| const bstr = await readFile(path, "ascii"); | ||||
| /* bstr is a binary string */ | ||||
| const workbook = XLSX.read(bstr, {type: "binary"}); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>NodeJS Server File Uploads</b> (click to show)</summary> | ||||
| 
 | ||||
| `read` can accept a NodeJS buffer.  `readFile` can read files generated by a | ||||
| HTTP POST request body parser like [`formidable`](https://npm.im/formidable): | ||||
| 
 | ||||
| ```js | ||||
| const XLSX = require("xlsx"); | ||||
| const http = require("http"); | ||||
| const formidable = require("formidable"); | ||||
| 
 | ||||
| const server = http.createServer((req, res) => { | ||||
|   const form = new formidable.IncomingForm(); | ||||
|   form.parse(req, (err, fields, files) => { | ||||
|     /* grab the first file */ | ||||
|     const f = Object.entries(files)[0][1]; | ||||
|     const path = f.filepath; | ||||
|     const workbook = XLSX.readFile(path); | ||||
| 
 | ||||
|     /* DO SOMETHING WITH workbook HERE */ | ||||
|   }); | ||||
| }).listen(process.env.PORT || 7262); | ||||
| ``` | ||||
| 
 | ||||
| The [`server` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/server) has more advanced examples. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Download files in a NodeJS process</b> (click to show)</summary> | ||||
| 
 | ||||
| Node 17.5 and 18.0 have native support for fetch: | ||||
| 
 | ||||
| ```js | ||||
| const XLSX = require("xlsx"); | ||||
| 
 | ||||
| const data = await (await fetch(url)).arrayBuffer(); | ||||
| /* data is an ArrayBuffer */ | ||||
| const workbook = XLSX.read(data); | ||||
| ``` | ||||
| 
 | ||||
| For broader compatibility, third-party modules are recommended. | ||||
| 
 | ||||
| [`request`](https://npm.im/request) requires a `null` encoding to yield Buffers: | ||||
| 
 | ||||
| ```js | ||||
| var XLSX = require("xlsx"); | ||||
| var request = require("request"); | ||||
| 
 | ||||
| request({url: url, encoding: null}, function(err, resp, body) { | ||||
|   var workbook = XLSX.read(body); | ||||
| 
 | ||||
|   /* DO SOMETHING WITH workbook HERE */ | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| [`axios`](https://npm.im/axios) works the same way in browser and in NodeJS: | ||||
| 
 | ||||
| ```js | ||||
| const XLSX = require("xlsx"); | ||||
| const axios = require("axios"); | ||||
| 
 | ||||
| (async() => { | ||||
|   const res = await axios.get(url, {responseType: "arraybuffer"}); | ||||
|   /* res.data is a Buffer */ | ||||
|   const workbook = XLSX.read(res.data); | ||||
| 
 | ||||
|   /* DO SOMETHING WITH workbook HERE */ | ||||
| })(); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Download files in an Electron app</b> (click to show)</summary> | ||||
| 
 | ||||
| The `net` module in the main process can make HTTP/HTTPS requests to external | ||||
| resources.  Responses should be manually concatenated using `Buffer.concat`: | ||||
| 
 | ||||
| ```js | ||||
| const XLSX = require("xlsx"); | ||||
| const { net } = require("electron"); | ||||
| 
 | ||||
| const req = net.request(url); | ||||
| req.on("response", (res) => { | ||||
|   const bufs = []; // this array will collect all of the buffers | ||||
|   res.on("data", (chunk) => { bufs.push(chunk); }); | ||||
|   res.on("end", () => { | ||||
|     const workbook = XLSX.read(Buffer.concat(bufs)); | ||||
| 
 | ||||
|     /* DO SOMETHING WITH workbook HERE */ | ||||
|   }); | ||||
| }); | ||||
| req.end(); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Readable Streams in NodeJS</b> (click to show)</summary> | ||||
| 
 | ||||
| When dealing with Readable Streams, the easiest approach is to buffer the stream | ||||
| and process the whole thing at the end: | ||||
| 
 | ||||
| ```js | ||||
| var fs = require("fs"); | ||||
| var XLSX = require("xlsx"); | ||||
| 
 | ||||
| function process_RS(stream, cb) { | ||||
|   var buffers = []; | ||||
|   stream.on("data", function(data) { buffers.push(data); }); | ||||
|   stream.on("end", function() { | ||||
|     var buffer = Buffer.concat(buffers); | ||||
|     var workbook = XLSX.read(buffer, {type:"buffer"}); | ||||
| 
 | ||||
|     /* DO SOMETHING WITH workbook IN THE CALLBACK */ | ||||
|     cb(workbook); | ||||
|   }); | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>ReadableStream in the browser</b> (click to show)</summary> | ||||
| 
 | ||||
| When dealing with `ReadableStream`, the easiest approach is to buffer the stream | ||||
| and process the whole thing at the end: | ||||
| 
 | ||||
| ```js | ||||
| // XLSX is a global from the standalone script | ||||
| 
 | ||||
| async function process_RS(stream) { | ||||
|   /* collect data */ | ||||
|   const buffers = []; | ||||
|   const reader = stream.getReader(); | ||||
|   for(;;) { | ||||
|     const res = await reader.read(); | ||||
|     if(res.value) buffers.push(res.value); | ||||
|     if(res.done) break; | ||||
|   } | ||||
| 
 | ||||
|   /* concat */ | ||||
|   const out = new Uint8Array(buffers.reduce((acc, v) => acc + v.length, 0)); | ||||
| 
 | ||||
|   let off = 0; | ||||
|   for(const u8 of buffers) { | ||||
|     out.set(u8, off); | ||||
|     off += u8.length; | ||||
|   } | ||||
| 
 | ||||
|   return out; | ||||
| } | ||||
| 
 | ||||
| const data = await process_RS(stream); | ||||
| /* data is Uint8Array */ | ||||
| const workbook = XLSX.read(data, {type: 'array'}); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| More detailed examples are covered in the [included demos](https://github.com/SheetJS/SheetJS/tree/master/demos/) | ||||
| 
 | ||||
| ## Processing JSON and JS Data | ||||
| 
 | ||||
| JSON and JS data tend to represent single worksheets.  This section will use a | ||||
| few utility functions to generate workbooks. | ||||
| 
 | ||||
| _Create a new Workbook_ | ||||
| 
 | ||||
| ```js | ||||
| var workbook = XLSX.utils.book_new(); | ||||
| ``` | ||||
| 
 | ||||
| The `book_new` utility function creates an empty workbook with no worksheets. | ||||
| 
 | ||||
| Spreadsheet software generally require at least one worksheet and enforce the | ||||
| requirement in the user interface.  This library enforces the requirement at | ||||
| write time, throwing errors if an empty workbook is passed to write functions. | ||||
| 
 | ||||
| 
 | ||||
| #### API | ||||
| 
 | ||||
| _Create a worksheet from an array of arrays of JS values_ | ||||
| 
 | ||||
| ```js | ||||
| var worksheet = XLSX.utils.aoa_to_sheet(aoa, opts); | ||||
| ``` | ||||
| 
 | ||||
| The `aoa_to_sheet` utility function walks an "array of arrays" in row-major | ||||
| order, generating a worksheet object.  The following snippet generates a sheet | ||||
| with cell `A1` set to the string `A1`, cell `B1` set to `B1`, etc: | ||||
| 
 | ||||
| ```js | ||||
| var worksheet = XLSX.utils.aoa_to_sheet([ | ||||
|   ["A1", "B1", "C1"], | ||||
|   ["A2", "B2", "C2"], | ||||
|   ["A3", "B3", "C3"] | ||||
| ]); | ||||
| ``` | ||||
| 
 | ||||
| ["Array of Arrays Input"](../api/utilities#array-of-arrays-input) describes the function and the | ||||
| optional `opts` argument in more detail. | ||||
| 
 | ||||
| 
 | ||||
| _Create a worksheet from an array of JS objects_ | ||||
| 
 | ||||
| ```js | ||||
| var worksheet = XLSX.utils.json_to_sheet(jsa, opts); | ||||
| ``` | ||||
| 
 | ||||
| The `json_to_sheet` utility function walks an array of JS objects in order, | ||||
| generating a worksheet object.  By default, it will generate a header row and | ||||
| one row per object in the array.  The optional `opts` argument has settings to | ||||
| control the column order and header output. | ||||
| 
 | ||||
| ["Array of Objects Input"](../api/utilities#array-of-objects-input) describes the function and | ||||
| the optional `opts` argument in more detail. | ||||
| 
 | ||||
| #### Examples | ||||
| 
 | ||||
| ["Complete Example"](../example) contains a detailed example "Get Data | ||||
| from a JSON Endpoint and Generate a Workbook" | ||||
| 
 | ||||
| 
 | ||||
| [`x-spreadsheet`](https://github.com/myliang/x-spreadsheet) is an interactive | ||||
| data grid for previewing and modifying structured data in the web browser.  The | ||||
| [`xspreadsheet` demo](https://github.com/sheetjs/sheetjs/tree/master/demos/xspreadsheet) includes a sample script with the | ||||
| `xtos` function for converting from x-spreadsheet data object to a workbook. | ||||
| <https://oss.sheetjs.com/sheetjs/x-spreadsheet> is a live demo. | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Records from a database query (SQL or no-SQL)</b> (click to show)</summary> | ||||
| 
 | ||||
| The [`database` demo](https://github.com/sheetjs/sheetjs/tree/master/demos/database/) includes examples of working with | ||||
| databases and query results. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Numerical Computations with TensorFlow.js</b> (click to show)</summary> | ||||
| 
 | ||||
| `@tensorflow/tfjs` and other libraries expect data in simple arrays, well-suited | ||||
| for worksheets where each column is a data vector.  That is the transpose of how | ||||
| most people use spreadsheets, where each row is a vector. | ||||
| 
 | ||||
| When recovering data from `tfjs`, the returned data points are stored in a typed | ||||
| array.  An array of arrays can be constructed with loops. `Array#unshift` can | ||||
| prepend a title row before the conversion: | ||||
| 
 | ||||
| ```js | ||||
| const XLSX = require("xlsx"); | ||||
| const tf = require('@tensorflow/tfjs'); | ||||
| 
 | ||||
| /* suppose xs and ys are vectors (1D tensors) -> tfarr will be a typed array */ | ||||
| const tfdata = tf.stack([xs, ys]).transpose(); | ||||
| const shape = tfdata.shape; | ||||
| const tfarr = tfdata.dataSync(); | ||||
| 
 | ||||
| /* construct the array of arrays */ | ||||
| const aoa = []; | ||||
| for(let j = 0; j < shape[0]; ++j) { | ||||
|   aoa[j] = []; | ||||
|   for(let i = 0; i < shape[1]; ++i) aoa[j][i] = tfarr[j * shape[1] + i]; | ||||
| } | ||||
| /* add headers to the top */ | ||||
| aoa.unshift(["x", "y"]); | ||||
| 
 | ||||
| /* generate worksheet */ | ||||
| const worksheet = XLSX.utils.aoa_to_sheet(aoa); | ||||
| ``` | ||||
| 
 | ||||
| The [`array` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/array/) shows a complete example. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| 
 | ||||
| ## Processing HTML Tables | ||||
| 
 | ||||
| #### API | ||||
| 
 | ||||
| _Create a worksheet by scraping an HTML TABLE in the page_ | ||||
| 
 | ||||
| ```js | ||||
| var worksheet = XLSX.utils.table_to_sheet(dom_element, opts); | ||||
| ``` | ||||
| 
 | ||||
| The `table_to_sheet` utility function takes a DOM TABLE element and iterates | ||||
| through the rows to generate a worksheet.  The `opts` argument is optional. | ||||
| ["HTML Table Input"](../api/utilities#html-table-input) describes the function in more detail. | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| _Create a workbook by scraping an HTML TABLE in the page_ | ||||
| 
 | ||||
| ```js | ||||
| var workbook = XLSX.utils.table_to_book(dom_element, opts); | ||||
| ``` | ||||
| 
 | ||||
| The `table_to_book` utility function follows the same logic as `table_to_sheet`. | ||||
| After generating a worksheet, it creates a blank workbook and appends the | ||||
| spreadsheet. | ||||
| 
 | ||||
| The options argument supports the same options as `table_to_sheet`, with the | ||||
| addition of a `sheet` property to control the worksheet name.  If the property | ||||
| is missing or no options are specified, the default name `Sheet1` is used. | ||||
| 
 | ||||
| #### Examples | ||||
| 
 | ||||
| Here are a few common scenarios (click on each subtitle to see the code): | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>HTML TABLE element in a webpage</b> (click to show)</summary> | ||||
| 
 | ||||
| ```html | ||||
| <!-- include the standalone script and shim.  this uses the UNPKG CDN --> | ||||
| <script src="https://cdn.sheetjs.com/xlsx-latest/package/dist/shim.min.js"></script> | ||||
| <script src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"></script> | ||||
| 
 | ||||
| <!-- example table with id attribute --> | ||||
| <table id="tableau"> | ||||
|   <tr><td>Sheet</td><td>JS</td></tr> | ||||
|   <tr><td>12345</td><td>67</td></tr> | ||||
| </table> | ||||
| 
 | ||||
| <!-- this block should appear after the table HTML and the standalone script --> | ||||
| <script type="text/javascript"> | ||||
|   var workbook = XLSX.utils.table_to_book(document.getElementById("tableau")); | ||||
| 
 | ||||
|   /* DO SOMETHING WITH workbook HERE */ | ||||
| </script> | ||||
| ``` | ||||
| 
 | ||||
| Multiple tables on a web page can be converted to individual worksheets: | ||||
| 
 | ||||
| ```js | ||||
| /* create new workbook */ | ||||
| var workbook = XLSX.utils.book_new(); | ||||
| 
 | ||||
| /* convert table "table1" to worksheet named "Sheet1" */ | ||||
| var sheet1 = XLSX.utils.table_to_sheet(document.getElementById("table1")); | ||||
| XLSX.utils.book_append_sheet(workbook, sheet1, "Sheet1"); | ||||
| 
 | ||||
| /* convert table "table2" to worksheet named "Sheet2" */ | ||||
| var sheet2 = XLSX.utils.table_to_sheet(document.getElementById("table2")); | ||||
| XLSX.utils.book_append_sheet(workbook, sheet2, "Sheet2"); | ||||
| 
 | ||||
| /* workbook now has 2 worksheets */ | ||||
| ``` | ||||
| 
 | ||||
| Alternatively, the HTML code can be extracted and parsed: | ||||
| 
 | ||||
| ```js | ||||
| var htmlstr = document.getElementById("tableau").outerHTML; | ||||
| var workbook = XLSX.read(htmlstr, {type:"string"}); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Chrome/Chromium Extension</b> (click to show)</summary> | ||||
| 
 | ||||
| The [`chrome` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/chrome/) shows a complete example and details the | ||||
| required permissions and other settings. | ||||
| 
 | ||||
| In an extension, it is recommended to generate the workbook in a content script | ||||
| and pass the object back to the extension: | ||||
| 
 | ||||
| ```js | ||||
| /* in the worker script */ | ||||
| chrome.runtime.onMessage.addListener(function(msg, sender, cb) { | ||||
|   /* pass a message like { sheetjs: true } from the extension to scrape */ | ||||
|   if(!msg || !msg.sheetjs) return; | ||||
|   /* create a new workbook */ | ||||
|   var workbook = XLSX.utils.book_new(); | ||||
|   /* loop through each table element */ | ||||
|   var tables = document.getElementsByTagName("table") | ||||
|   for(var i = 0; i < tables.length; ++i) { | ||||
|     var worksheet = XLSX.utils.table_to_sheet(tables[i]); | ||||
|     XLSX.utils.book_append_sheet(workbook, worksheet, "Table" + i); | ||||
|   } | ||||
|   /* pass back to the extension */ | ||||
|   return cb(workbook); | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Server-Side HTML Tables with Headless Chrome</b> (click to show)</summary> | ||||
| 
 | ||||
| The [`headless` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/headless/) includes a complete demo to convert HTML | ||||
| files to XLSB workbooks.  The core idea is to add the script to the page, parse | ||||
| the table in the page context, generate a `base64` workbook and send it back | ||||
| for further processing: | ||||
| 
 | ||||
| ```js | ||||
| const XLSX = require("xlsx"); | ||||
| const { readFileSync } = require("fs"), puppeteer = require("puppeteer"); | ||||
| 
 | ||||
| const url = `https://sheetjs.com/demos/table`; | ||||
| 
 | ||||
| /* get the standalone build source (node_modules/xlsx/dist/xlsx.full.min.js) */ | ||||
| const lib = readFileSync(require.resolve("xlsx/dist/xlsx.full.min.js"), "utf8"); | ||||
| 
 | ||||
| (async() => { | ||||
|   /* start browser and go to web page */ | ||||
|   const browser = await puppeteer.launch(); | ||||
|   const page = await browser.newPage(); | ||||
|   await page.goto(url, {waitUntil: "networkidle2"}); | ||||
| 
 | ||||
|   /* inject library */ | ||||
|   await page.addScriptTag({content: lib}); | ||||
| 
 | ||||
|   /* this function `s5s` will be called by the script below, receiving the Base64-encoded file */ | ||||
|   await page.exposeFunction("s5s", async(b64) => { | ||||
|     const workbook = XLSX.read(b64, {type: "base64" }); | ||||
| 
 | ||||
|     /* DO SOMETHING WITH workbook HERE */ | ||||
|   }); | ||||
| 
 | ||||
|   /* generate XLSB file in webpage context and send back result */ | ||||
|   await page.addScriptTag({content: ` | ||||
|     /* call table_to_book on first table */ | ||||
|     var workbook = XLSX.utils.table_to_book(document.querySelector("TABLE")); | ||||
| 
 | ||||
|     /* generate XLSX file */ | ||||
|     var b64 = XLSX.write(workbook, {type: "base64", bookType: "xlsb"}); | ||||
| 
 | ||||
|     /* call "s5s" hook exposed from the node process */ | ||||
|     window.s5s(b64); | ||||
|   `}); | ||||
| 
 | ||||
|   /* cleanup */ | ||||
|   await browser.close(); | ||||
| })(); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Server-Side HTML Tables with Headless WebKit</b> (click to show)</summary> | ||||
| 
 | ||||
| The [`headless` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/headless/) includes a complete demo to convert HTML | ||||
| files to XLSB workbooks using [PhantomJS](https://phantomjs.org/). The core idea | ||||
| is to add the script to the page, parse the table in the page context, generate | ||||
| a `binary` workbook and send it back for further processing: | ||||
| 
 | ||||
| ```js | ||||
| var XLSX = require('xlsx'); | ||||
| var page = require('webpage').create(); | ||||
| 
 | ||||
| /* this code will be run in the page */ | ||||
| var code = [ "function(){", | ||||
|   /* call table_to_book on first table */ | ||||
|   "var wb = XLSX.utils.table_to_book(document.body.getElementsByTagName('table')[0]);", | ||||
| 
 | ||||
|   /* generate XLSB file and return binary string */ | ||||
|   "return XLSX.write(wb, {type: 'binary', bookType: 'xlsb'});", | ||||
| "}" ].join(""); | ||||
| 
 | ||||
| page.open('https://sheetjs.com/demos/table', function() { | ||||
|   /* Load the browser script from the UNPKG CDN */ | ||||
|   page.includeJs("https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js", function() { | ||||
|     /* The code will return an XLSB file encoded as binary string */ | ||||
|     var bin = page.evaluateJavaScript(code); | ||||
| 
 | ||||
|     var workbook = XLSX.read(bin, {type: "binary"}); | ||||
|     /* DO SOMETHING WITH workbook HERE */ | ||||
| 
 | ||||
|     phantom.exit(); | ||||
|   }); | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>NodeJS HTML Tables without a browser</b> (click to show)</summary> | ||||
| 
 | ||||
| NodeJS does not include a DOM implementation and Puppeteer requires a hefty | ||||
| Chromium build.  [`jsdom`](https://npm.im/jsdom) is a lightweight alternative: | ||||
| 
 | ||||
| ```js | ||||
| const XLSX = require("xlsx"); | ||||
| const { readFileSync } = require("fs"); | ||||
| const { JSDOM } = require("jsdom"); | ||||
| 
 | ||||
| /* obtain HTML string.  This example reads from test.html */ | ||||
| const html_str = fs.readFileSync("test.html", "utf8"); | ||||
| /* get first TABLE element */ | ||||
| const doc = new JSDOM(html_str).window.document.querySelector("table"); | ||||
| /* generate workbook */ | ||||
| const workbook = XLSX.utils.table_to_book(doc); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
							
								
								
									
										139
									
								
								docz/docs/06-solutions/03-processing.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,139 @@ | ||||
| --- | ||||
| sidebar_position: 3 | ||||
| --- | ||||
| 
 | ||||
| # Data Processing | ||||
| 
 | ||||
| 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 | ||||
| 
 | ||||
| #### API | ||||
| 
 | ||||
| _Append a Worksheet to a Workbook_ | ||||
| 
 | ||||
| ```js | ||||
| XLSX.utils.book_append_sheet(workbook, worksheet, sheet_name); | ||||
| ``` | ||||
| 
 | ||||
| The `book_append_sheet` utility function appends a worksheet to the workbook. | ||||
| The third argument specifies the desired worksheet name. Multiple worksheets can | ||||
| be added to a workbook by calling the function multiple times.  If the worksheet | ||||
| name is already used in the workbook, it will throw an error. | ||||
| 
 | ||||
| _Append a Worksheet to a Workbook and find a unique name_ | ||||
| 
 | ||||
| ```js | ||||
| var new_name = XLSX.utils.book_append_sheet(workbook, worksheet, name, true); | ||||
| ``` | ||||
| 
 | ||||
| If the fourth argument is `true`, the function will start with the specified | ||||
| worksheet name.  If the sheet name exists in the workbook, a new worksheet name | ||||
| will be chosen by finding the name stem and incrementing the counter: | ||||
| 
 | ||||
| ```js | ||||
| XLSX.utils.book_append_sheet(workbook, sheetA, "Sheet2", true); // Sheet2 | ||||
| XLSX.utils.book_append_sheet(workbook, sheetB, "Sheet2", true); // Sheet3 | ||||
| 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 | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Add a new worksheet to a workbook</b> (click to show)</summary> | ||||
| 
 | ||||
| This example uses [`XLSX.utils.aoa_to_sheet`](../api/utilities#array-of-arrays-input). | ||||
| 
 | ||||
| ```js | ||||
| var ws_name = "SheetJS"; | ||||
| 
 | ||||
| /* Create worksheet */ | ||||
| var ws_data = [ | ||||
|   [ "S", "h", "e", "e", "t", "J", "S" ], | ||||
|   [  1 ,  2 ,  3 ,  4 ,  5 ] | ||||
| ]; | ||||
| var ws = XLSX.utils.aoa_to_sheet(ws_data); | ||||
| 
 | ||||
| /* Add the worksheet to the workbook */ | ||||
| XLSX.utils.book_append_sheet(wb, ws, ws_name); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ## Modifying Cell Values | ||||
| 
 | ||||
| #### API | ||||
| 
 | ||||
| _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_ | ||||
| 
 | ||||
| ```js | ||||
| XLSX.utils.sheet_add_aoa(worksheet, aoa, opts); | ||||
| ``` | ||||
| 
 | ||||
| The `sheet_add_aoa` utility function modifies cell values in a worksheet.  The | ||||
| first argument is the worksheet object.  The second argument is an array of | ||||
| arrays of values.  The `origin` key of the third argument controls where cells | ||||
| will be written.  The following snippet sets `B3=1` and `E5="abc"`: | ||||
| 
 | ||||
| ```js | ||||
| XLSX.utils.sheet_add_aoa(worksheet, [ | ||||
|   [1],                             // <-- Write 1 to cell B3 | ||||
|   ,                                // <-- Do nothing in row 4 | ||||
|   [/*B5*/, /*C5*/, /*D5*/, "abc"]  // <-- Write "abc" to cell E5 | ||||
| ], { origin: "B3" }); | ||||
| ``` | ||||
| 
 | ||||
| ["Array of Arrays Input"](../api/utilities#array-of-arrays-input) describes the | ||||
| function and the optional `opts` argument in more detail. | ||||
| 
 | ||||
| #### Examples | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Appending rows to a worksheet</b> (click to show)</summary> | ||||
| 
 | ||||
| The special origin value `-1` instructs `sheet_add_aoa` to start in column A of | ||||
| the row after the last row in the range, appending the data: | ||||
| 
 | ||||
| ```js | ||||
| XLSX.utils.sheet_add_aoa(worksheet, [ | ||||
|   ["first row after data", 1], | ||||
|   ["second row after data", 2] | ||||
| ], { origin: -1 }); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ## Modifying Other Worksheet / Workbook / Cell Properties | ||||
| 
 | ||||
| The ["Common Spreadsheet Format"](../csf/general) section describes | ||||
| the object structures in greater detail. | ||||
| 
 | ||||
							
								
								
									
										624
									
								
								docz/docs/06-solutions/05-output.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,624 @@ | ||||
| --- | ||||
| sidebar_position: 5 | ||||
| --- | ||||
| 
 | ||||
| # Data Export | ||||
| 
 | ||||
| ## Writing Workbooks | ||||
| 
 | ||||
| #### API | ||||
| 
 | ||||
| _Generate spreadsheet bytes (file) from data_ | ||||
| 
 | ||||
| ```js | ||||
| var data = XLSX.write(workbook, opts); | ||||
| ``` | ||||
| 
 | ||||
| The `write` method attempts to package data from the workbook into a file in | ||||
| memory.  By default, XLSX files are generated, but that can be controlled with | ||||
| the `bookType` property of the `opts` argument.  Based on the `type` option, | ||||
| the data can be stored as a "binary string", JS string, `Uint8Array` or Buffer. | ||||
| 
 | ||||
| The second `opts` argument is required.  ["Writing Options"](../api/write-options) | ||||
| covers the supported properties and behaviors. | ||||
| 
 | ||||
| _Generate and attempt to save file_ | ||||
| 
 | ||||
| ```js | ||||
| XLSX.writeFile(workbook, filename, opts); | ||||
| ``` | ||||
| 
 | ||||
| The `writeFile` method packages the data and attempts to save the new file.  The | ||||
| export file format is determined by the extension of `filename` (`SheetJS.xlsx` | ||||
| signals XLSX export, `SheetJS.xlsb` signals XLSB export, etc). | ||||
| 
 | ||||
| The `writeFile` method uses platform-specific APIs to initiate the file save. In | ||||
| NodeJS, `fs.readFileSync` can create a file.  In the web browser, a download is | ||||
| attempted using the HTML5 `download` attribute, with fallbacks for IE. | ||||
| 
 | ||||
| _Generate and attempt to save an XLSX file_ | ||||
| 
 | ||||
| ```js | ||||
| XLSX.writeFileXLSX(workbook, filename, opts); | ||||
| ``` | ||||
| 
 | ||||
| The `writeFile` method embeds a number of different export functions.  This is | ||||
| great for developer experience but not amenable to tree shaking using the | ||||
| current developer tools.  When only XLSX exports are needed, this method avoids | ||||
| referencing the other export functions. | ||||
| 
 | ||||
| The second `opts` argument is optional.  ["Writing Options"](../api/write-options) | ||||
| covers the supported properties and behaviors. | ||||
| 
 | ||||
| #### Examples | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Local file in a NodeJS server</b> (click to show)</summary> | ||||
| 
 | ||||
| `writeFile` uses `fs.writeFileSync` in server environments: | ||||
| 
 | ||||
| ```js | ||||
| var XLSX = require("xlsx"); | ||||
| 
 | ||||
| /* output format determined by filename */ | ||||
| XLSX.writeFile(workbook, "out.xlsb"); | ||||
| ``` | ||||
| 
 | ||||
| For Node ESM, the `writeFile` helper is not enabled. Instead, `fs.writeFileSync` | ||||
| should be used to write the file data to a `Buffer` for use with `XLSX.write`: | ||||
| 
 | ||||
| ```js | ||||
| import { writeFileSync } from "fs"; | ||||
| import { write } from "xlsx/xlsx.mjs"; | ||||
| 
 | ||||
| const buf = write(workbook, {type: "buffer", bookType: "xlsb"}); | ||||
| /* buf is a Buffer */ | ||||
| const workbook = writeFileSync("out.xlsb", buf); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Local file in a Deno application</b> (click to show)</summary> | ||||
| 
 | ||||
| `writeFile` uses `Deno.writeFileSync` under the hood: | ||||
| 
 | ||||
| ```js | ||||
| // @deno-types="https://deno.land/x/sheetjs/types/index.d.ts" | ||||
| import * as XLSX from 'https://deno.land/x/sheetjs/xlsx.mjs' | ||||
| 
 | ||||
| XLSX.writeFile(workbook, "test.xlsx"); | ||||
| ``` | ||||
| 
 | ||||
| Applications writing files must be invoked with the `--allow-write` flag.  The | ||||
| [`deno` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/deno/) has more examples | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Local file in a PhotoShop or InDesign plugin</b> (click to show)</summary> | ||||
| 
 | ||||
| `writeFile` wraps the `File` logic in Photoshop and other ExtendScript targets. | ||||
| The specified path should be an absolute path: | ||||
| 
 | ||||
| ```js | ||||
| #include "xlsx.extendscript.js" | ||||
| 
 | ||||
| /* output format determined by filename */ | ||||
| XLSX.writeFile(workbook, "out.xlsx"); | ||||
| /* at this point, out.xlsx is a file that you can distribute */ | ||||
| ``` | ||||
| 
 | ||||
| The [`extendscript` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/extendscript/) includes a more complex example. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Download a file in the browser to the user machine</b> (click to show)</summary> | ||||
| 
 | ||||
| `XLSX.writeFile` wraps a few techniques for triggering a file save: | ||||
| 
 | ||||
| - `URL` browser API creates an object URL for the file, which the library uses | ||||
|   by creating a link and forcing a click. It is supported in modern browsers. | ||||
| - `msSaveBlob` is an IE10+ API for triggering a file save. | ||||
| - `IE_FileSave` uses VBScript and ActiveX to write a file in IE6+ for Windows | ||||
|   XP and Windows 7.  The shim must be included in the containing HTML page. | ||||
| 
 | ||||
| There is no standard way to determine if the actual file has been downloaded. | ||||
| 
 | ||||
| ```js | ||||
| /* output format determined by filename */ | ||||
| XLSX.writeFile(workbook, "out.xlsb"); | ||||
| /* at this point, out.xlsb will have been downloaded */ | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Download a file in legacy browsers</b> (click to show)</summary> | ||||
| 
 | ||||
| `XLSX.writeFile` techniques work for most modern browsers as well as older IE. | ||||
| For much older browsers, there are workarounds implemented by wrapper libraries. | ||||
| 
 | ||||
| [`FileSaver.js`](https://github.com/eligrey/FileSaver.js/) implements `saveAs`. | ||||
| Note: `XLSX.writeFile` will automatically call `saveAs` if available. | ||||
| 
 | ||||
| ```js | ||||
| /* bookType can be any supported output type */ | ||||
| var wopts = { bookType:"xlsx", bookSST:false, type:"array" }; | ||||
| 
 | ||||
| var wbout = XLSX.write(workbook,wopts); | ||||
| 
 | ||||
| /* the saveAs call downloads a file on the local machine */ | ||||
| saveAs(new Blob([wbout],{type:"application/octet-stream"}), "test.xlsx"); | ||||
| ``` | ||||
| 
 | ||||
| [`Downloadify`](https://github.com/dcneiner/downloadify) uses a Flash SWF button | ||||
| to generate local files, suitable for environments where ActiveX is unavailable: | ||||
| 
 | ||||
| ```js | ||||
| Downloadify.create(id,{ | ||||
|   /* other options are required! read the downloadify docs for more info */ | ||||
|   filename: "test.xlsx", | ||||
|   data: function() { return XLSX.write(wb, {bookType:"xlsx", type:"base64"}); }, | ||||
|   append: false, | ||||
|   dataType: "base64" | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| The [`oldie` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/oldie/) shows an IE-compatible fallback scenario. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Browser upload file (ajax)</b> (click to show)</summary> | ||||
| 
 | ||||
| A complete example using XHR is [included in the XHR demo](https://github.com/SheetJS/SheetJS/tree/master/demos/xhr/), along | ||||
| with examples for fetch and wrapper libraries.  This example assumes the server | ||||
| can handle Base64-encoded files (see the demo for a basic nodejs server): | ||||
| 
 | ||||
| ```js | ||||
| /* in this example, send a base64 string to the server */ | ||||
| var wopts = { bookType:"xlsx", bookSST:false, type:"base64" }; | ||||
| 
 | ||||
| var wbout = XLSX.write(workbook,wopts); | ||||
| 
 | ||||
| var req = new XMLHttpRequest(); | ||||
| req.open("POST", "/upload", true); | ||||
| var formdata = new FormData(); | ||||
| formdata.append("file", "test.xlsx"); // <-- server expects `file` to hold name | ||||
| formdata.append("data", wbout); // <-- `data` holds the base64-encoded data | ||||
| req.send(formdata); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>PhantomJS (Headless Webkit) File Generation</b> (click to show)</summary> | ||||
| 
 | ||||
| The [`headless` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/headless/) includes a complete demo to convert HTML | ||||
| files to XLSB workbooks using [PhantomJS](https://phantomjs.org/). PhantomJS | ||||
| `fs.write` supports writing files from the main process but has a different | ||||
| interface from the NodeJS `fs` module: | ||||
| 
 | ||||
| ```js | ||||
| var XLSX = require('xlsx'); | ||||
| var fs = require('fs'); | ||||
| 
 | ||||
| /* generate a binary string */ | ||||
| var bin = XLSX.write(workbook, { type:"binary", bookType: "xlsx" }); | ||||
| /* write to file */ | ||||
| fs.write("test.xlsx", bin, "wb"); | ||||
| ``` | ||||
| 
 | ||||
| Note: The section ["Processing HTML Tables"](./input#processing-html-tables) shows how | ||||
| to generate a workbook from HTML tables in a page in "Headless WebKit". | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| The [included demos](https://github.com/SheetJS/SheetJS/tree/master/demos/) cover mobile apps and other special deployments. | ||||
| 
 | ||||
| ### Writing Examples | ||||
| 
 | ||||
| - <http://sheetjs.com/demos/table.html> exporting an HTML table | ||||
| - <http://sheetjs.com/demos/writexlsx.html> generates a simple file | ||||
| 
 | ||||
| ### Streaming Write | ||||
| 
 | ||||
| The streaming write functions are available in the `XLSX.stream` object.  They | ||||
| take the same arguments as the normal write functions but return a NodeJS | ||||
| Readable Stream. | ||||
| 
 | ||||
| - `XLSX.stream.to_csv` is the streaming version of `XLSX.utils.sheet_to_csv`. | ||||
| - `XLSX.stream.to_html` is the streaming version of `XLSX.utils.sheet_to_html`. | ||||
| - `XLSX.stream.to_json` is the streaming version of `XLSX.utils.sheet_to_json`. | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>nodejs convert to CSV and write file</b> (click to show)</summary> | ||||
| 
 | ||||
| ```js | ||||
| var output_file_name = "out.csv"; | ||||
| var stream = XLSX.stream.to_csv(worksheet); | ||||
| stream.pipe(fs.createWriteStream(output_file_name)); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>nodejs write JSON stream to screen</b> (click to show)</summary> | ||||
| 
 | ||||
| ```js | ||||
| /* to_json returns an object-mode stream */ | ||||
| var stream = XLSX.stream.to_json(worksheet, {raw:true}); | ||||
| 
 | ||||
| /* the following stream converts JS objects to text via JSON.stringify */ | ||||
| var conv = new Transform({writableObjectMode:true}); | ||||
| conv._transform = function(obj, e, cb){ cb(null, JSON.stringify(obj) + "\n"); }; | ||||
| 
 | ||||
| stream.pipe(conv); conv.pipe(process.stdout); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Exporting NUMBERS files</b> (click to show)</summary> | ||||
| 
 | ||||
| The NUMBERS writer requires a fairly large base.  The supplementary `xlsx.zahl` | ||||
| scripts provide support.  `xlsx.zahl.js` is designed for standalone and NodeJS | ||||
| use, while `xlsx.zahl.mjs` is suitable for ESM. | ||||
| 
 | ||||
| _Browser_ | ||||
| 
 | ||||
| ```html | ||||
| <meta charset="utf8"> | ||||
| <script src="xlsx.full.min.js"></script> | ||||
| <script src="xlsx.zahl.js"></script> | ||||
| <script> | ||||
| var wb = XLSX.utils.book_new(); var ws = XLSX.utils.aoa_to_sheet([ | ||||
|   ["SheetJS", "<3","விரிதாள்"], | ||||
|   [72,,"Arbeitsblätter"], | ||||
|   [,62,"数据"], | ||||
|   [true,false,], | ||||
| ]); XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); | ||||
| XLSX.writeFile(wb, "textport.numbers", {numbers: XLSX_ZAHL, compression: true}); | ||||
| </script> | ||||
| ``` | ||||
| 
 | ||||
| _Node_ | ||||
| 
 | ||||
| ```js | ||||
| var XLSX = require("./xlsx.flow"); | ||||
| var XLSX_ZAHL = require("./dist/xlsx.zahl"); | ||||
| var wb = XLSX.utils.book_new(); var ws = XLSX.utils.aoa_to_sheet([ | ||||
|   ["SheetJS", "<3","விரிதாள்"], | ||||
|   [72,,"Arbeitsblätter"], | ||||
|   [,62,"数据"], | ||||
|   [true,false,], | ||||
| ]); XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); | ||||
| XLSX.writeFile(wb, "textport.numbers", {numbers: XLSX_ZAHL, compression: true}); | ||||
| ``` | ||||
| 
 | ||||
| _Deno_ | ||||
| 
 | ||||
| ```ts | ||||
| import * as XLSX from './xlsx.mjs'; | ||||
| import XLSX_ZAHL from './dist/xlsx.zahl.mjs'; | ||||
| 
 | ||||
| var wb = XLSX.utils.book_new(); var ws = XLSX.utils.aoa_to_sheet([ | ||||
|   ["SheetJS", "<3","விரிதாள்"], | ||||
|   [72,,"Arbeitsblätter"], | ||||
|   [,62,"数据"], | ||||
|   [true,false,], | ||||
| ]); XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); | ||||
| XLSX.writeFile(wb, "textports.numbers", {numbers: XLSX_ZAHL, compression: true}); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <https://github.com/sheetjs/sheetaki> pipes write streams to nodejs response. | ||||
| 
 | ||||
| ### Generating JSON and JS Data | ||||
| 
 | ||||
| JSON and JS data tend to represent single worksheets. The utility functions in | ||||
| this section work with single worksheets. | ||||
| 
 | ||||
| The ["Common Spreadsheet Format"](../csf/general) section describes | ||||
| the object structure in more detail.  `workbook.SheetNames` is an ordered list | ||||
| of the worksheet names.  `workbook.Sheets` is an object whose keys are sheet | ||||
| names and whose values are worksheet objects. | ||||
| 
 | ||||
| The "first worksheet" is stored at `workbook.Sheets[workbook.SheetNames[0]]`. | ||||
| 
 | ||||
| #### API | ||||
| 
 | ||||
| _Create an array of JS objects from a worksheet_ | ||||
| 
 | ||||
| ```js | ||||
| var jsa = XLSX.utils.sheet_to_json(worksheet, opts); | ||||
| ``` | ||||
| 
 | ||||
| _Create an array of arrays of JS values from a worksheet_ | ||||
| 
 | ||||
| ```js | ||||
| var aoa = XLSX.utils.sheet_to_json(worksheet, {...opts, header: 1}); | ||||
| ``` | ||||
| 
 | ||||
| The `sheet_to_json` utility function walks a workbook in row-major order, | ||||
| generating an array of objects.  The second `opts` argument controls a number of | ||||
| export decisions including the type of values (JS values or formatted text). The | ||||
| ["JSON"](../api/utilities#json) section describes the argument in more detail. | ||||
| 
 | ||||
| By default, `sheet_to_json` scans the first row and uses the values as headers. | ||||
| With the `header: 1` option, the function exports an array of arrays of values. | ||||
| 
 | ||||
| #### Examples | ||||
| 
 | ||||
| [`x-spreadsheet`](https://github.com/myliang/x-spreadsheet) is an interactive | ||||
| data grid for previewing and modifying structured data in the web browser.  The | ||||
| [`xspreadsheet` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/xspreadsheet) includes a sample script with the | ||||
| `stox` function for converting from a workbook to x-spreadsheet data object. | ||||
| <https://oss.sheetjs.com/sheetjs/x-spreadsheet> is a live demo. | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Previewing data in a React data grid</b> (click to show)</summary> | ||||
| 
 | ||||
| [`react-data-grid`](https://npm.im/react-data-grid) is a data grid tailored for | ||||
| react.  It expects two properties: `rows` of data objects and `columns` which | ||||
| describe the columns.  For the purposes of massaging the data to fit the react | ||||
| data grid API it is easiest to start from an array of arrays. | ||||
| 
 | ||||
| This demo starts by fetching a remote file and using `XLSX.read` to extract: | ||||
| 
 | ||||
| ```js | ||||
| import { useEffect, useState } from "react"; | ||||
| import DataGrid from "react-data-grid"; | ||||
| import { read, utils } from "xlsx"; | ||||
| 
 | ||||
| const url = "https://oss.sheetjs.com/test_files/RkNumber.xls"; | ||||
| 
 | ||||
| export default function App() { | ||||
|   const [columns, setColumns] = useState([]); | ||||
|   const [rows, setRows] = useState([]); | ||||
|   useEffect(() => {(async () => { | ||||
|     const wb = read(await (await fetch(url)).arrayBuffer(), { WTF: 1 }); | ||||
| 
 | ||||
|     /* use sheet_to_json with header: 1 to generate an array of arrays */ | ||||
|     const data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], { header: 1 }); | ||||
| 
 | ||||
|     /* see react-data-grid docs to understand the shape of the expected data */ | ||||
|     setColumns(data[0].map((r) => ({ key: r, name: r }))); | ||||
|     setRows(data.slice(1).map((r) => r.reduce((acc, x, i) => { | ||||
|       acc[data[0][i]] = x; | ||||
|       return acc; | ||||
|     }, {}))); | ||||
|   })(); }); | ||||
| 
 | ||||
|   return <DataGrid columns={columns} rows={rows} />; | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Previewing data in a VueJS data grid</b> (click to show)</summary> | ||||
| 
 | ||||
| [`vue3-table-lite`](https://github.com/linmasahiro/vue3-table-lite) is a simple | ||||
| VueJS 3 data table.  It is featured [in the VueJS demo](https://github.com/SheetJS/SheetJS/tree/master/demos/vue/modify/). | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Populating a database (SQL or no-SQL)</b> (click to show)</summary> | ||||
| 
 | ||||
| The [`database` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/database/) includes examples of working with | ||||
| databases and query results. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Numerical Computations with TensorFlow.js</b> (click to show)</summary> | ||||
| 
 | ||||
| `@tensorflow/tfjs` and other libraries expect data in simple arrays, well-suited | ||||
| for worksheets where each column is a data vector.  That is the transpose of how | ||||
| most people use spreadsheets, where each row is a vector. | ||||
| 
 | ||||
| A single `Array#map` can pull individual named rows from `sheet_to_json` export: | ||||
| 
 | ||||
| ```js | ||||
| const XLSX = require("xlsx"); | ||||
| const tf = require('@tensorflow/tfjs'); | ||||
| 
 | ||||
| const key = "age"; // this is the field we want to pull | ||||
| const ages = XLSX.utils.sheet_to_json(worksheet).map(r => r[key]); | ||||
| const tf_data = tf.tensor1d(ages); | ||||
| ``` | ||||
| 
 | ||||
| All fields can be processed at once using a transpose of the 2D tensor generated | ||||
| with the `sheet_to_json` export with `header: 1`. The first row, if it contains | ||||
| header labels, should be removed with a slice: | ||||
| 
 | ||||
| ```js | ||||
| const XLSX = require("xlsx"); | ||||
| const tf = require('@tensorflow/tfjs'); | ||||
| 
 | ||||
| /* array of arrays of the data starting on the second row */ | ||||
| const aoa = XLSX.utils.sheet_to_json(worksheet, {header: 1}).slice(1); | ||||
| /* dataset in the "correct orientation" */ | ||||
| const tf_dataset = tf.tensor2d(aoa).transpose(); | ||||
| /* pull out each dataset with a slice */ | ||||
| const tf_field0 = tf_dataset.slice([0,0], [1,tensor.shape[1]]).flatten(); | ||||
| const tf_field1 = tf_dataset.slice([1,0], [1,tensor.shape[1]]).flatten(); | ||||
| ``` | ||||
| 
 | ||||
| The [`array` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/array/) shows a complete example. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| 
 | ||||
| ### Generating HTML Tables | ||||
| 
 | ||||
| #### API | ||||
| 
 | ||||
| _Generate HTML Table from Worksheet_ | ||||
| 
 | ||||
| ```js | ||||
| var html = XLSX.utils.sheet_to_html(worksheet); | ||||
| ``` | ||||
| 
 | ||||
| The `sheet_to_html` utility function generates HTML code based on the worksheet | ||||
| data.  Each cell in the worksheet is mapped to a `<TD>` element.  Merged cells | ||||
| in the worksheet are serialized by setting `colspan` and `rowspan` attributes. | ||||
| 
 | ||||
| #### Examples | ||||
| 
 | ||||
| The `sheet_to_html` utility function generates HTML code that can be added to | ||||
| any DOM element by setting the `innerHTML`: | ||||
| 
 | ||||
| ```js | ||||
| var container = document.getElementById("tavolo"); | ||||
| container.innerHTML = XLSX.utils.sheet_to_html(worksheet); | ||||
| ``` | ||||
| 
 | ||||
| Combining with `fetch`, constructing a site from a workbook is straightforward: | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Vanilla JS + HTML fetch workbook and generate table previews</b> (click to show)</summary> | ||||
| 
 | ||||
| ```html | ||||
| <body> | ||||
|   <style>TABLE { border-collapse: collapse; } TD { border: 1px solid; }</style> | ||||
|   <div id="tavolo"></div> | ||||
|   <script src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"></script> | ||||
|   <script type="text/javascript"> | ||||
| (async() => { | ||||
|   /* fetch and parse workbook -- see the fetch example for details */ | ||||
|   const workbook = XLSX.read(await (await fetch("sheetjs.xlsx")).arrayBuffer()); | ||||
| 
 | ||||
|   let output = []; | ||||
|   /* loop through the worksheet names in order */ | ||||
|   workbook.SheetNames.forEach(name => { | ||||
| 
 | ||||
|     /* generate HTML from the corresponding worksheets */ | ||||
|     const worksheet = workbook.Sheets[name]; | ||||
|     const html = XLSX.utils.sheet_to_html(worksheet); | ||||
| 
 | ||||
|     /* add a header with the title name followed by the table */ | ||||
|     output.push(`<H3>${name}</H3>${html}`); | ||||
|   }); | ||||
|   /* write to the DOM at the end */ | ||||
|   tavolo.innerHTML = output.join("\n"); | ||||
| })(); | ||||
|   </script> | ||||
| </body> | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>React fetch workbook and generate HTML table previews</b> (click to show)</summary> | ||||
| 
 | ||||
| It is generally recommended to use a React-friendly workflow, but it is possible | ||||
| to generate HTML and use it in React with `dangerouslySetInnerHTML`: | ||||
| 
 | ||||
| ```jsx | ||||
| function Tabeller(props) { | ||||
|   /* the workbook object is the state */ | ||||
|   const [workbook, setWorkbook] = React.useState(XLSX.utils.book_new()); | ||||
| 
 | ||||
|   /* fetch and update the workbook with an effect */ | ||||
|   React.useEffect(() => { (async() => { | ||||
|     /* fetch and parse workbook -- see the fetch example for details */ | ||||
|     const wb = XLSX.read(await (await fetch("sheetjs.xlsx")).arrayBuffer()); | ||||
|     setWorkbook(wb); | ||||
|   })(); }); | ||||
| 
 | ||||
|   return workbook.SheetNames.map(name => (<> | ||||
|     <h3>name</h3> | ||||
|     <div dangerouslySetInnerHTML={{ | ||||
|       /* this __html mantra is needed to set the inner HTML */ | ||||
|       __html: XLSX.utils.sheet_to_html(workbook.Sheets[name]) | ||||
|     }} /> | ||||
|   </>)); | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| The [`react` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/react) includes more React examples. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>VueJS fetch workbook and generate HTML table previews</b> (click to show)</summary> | ||||
| 
 | ||||
| It is generally recommended to use a VueJS-friendly workflow, but it is possible | ||||
| to generate HTML and use it in VueJS with the `v-html` directive: | ||||
| 
 | ||||
| ```jsx | ||||
| import { read, utils } from 'xlsx'; | ||||
| import { reactive } from 'vue'; | ||||
| 
 | ||||
| const S5SComponent = { | ||||
|   mounted() { (async() => { | ||||
|     /* fetch and parse workbook -- see the fetch example for details */ | ||||
|     const workbook = read(await (await fetch("sheetjs.xlsx")).arrayBuffer()); | ||||
|     /* loop through the worksheet names in order */ | ||||
|     workbook.SheetNames.forEach(name => { | ||||
|       /* generate HTML from the corresponding worksheets */ | ||||
|       const html = utils.sheet_to_html(workbook.Sheets[name]); | ||||
|       /* add to state */ | ||||
|       this.wb.wb.push({ name, html }); | ||||
|     }); | ||||
|   })(); }, | ||||
|   /* this state mantra is required for array updates to work */ | ||||
|   setup() { return { wb: reactive({ wb: [] }) }; }, | ||||
|   template: ` | ||||
|   <div v-for="ws in wb.wb" :key="ws.name"> | ||||
|     <h3>{{ ws.name }}</h3> | ||||
|     <div v-html="ws.html"></div> | ||||
|   </div>` | ||||
| }; | ||||
| ``` | ||||
| 
 | ||||
| The [`vuejs` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/vue) includes more React examples. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ### Generating Single-Worksheet Snapshots | ||||
| 
 | ||||
| The `sheet_to_*` functions accept a worksheet object. | ||||
| 
 | ||||
| #### API | ||||
| 
 | ||||
| _Generate a CSV from a single worksheet_ | ||||
| 
 | ||||
| ```js | ||||
| var csv = XLSX.utils.sheet_to_csv(worksheet, opts); | ||||
| ``` | ||||
| 
 | ||||
| This snapshot is designed to replicate the "CSV UTF8 (`.csv`)" output type. | ||||
| ["Delimiter-Separated Output"](../api/utilities#delimiter-separated-output) describes the | ||||
| function and the optional `opts` argument in more detail. | ||||
| 
 | ||||
| _Generate "Text" from a single worksheet_ | ||||
| 
 | ||||
| ```js | ||||
| var txt = XLSX.utils.sheet_to_txt(worksheet, opts); | ||||
| ``` | ||||
| 
 | ||||
| This snapshot is designed to replicate the "UTF16 Text (`.txt`)" output type. | ||||
| ["Delimiter-Separated Output"](../api/utilities#delimiter-separated-output) describes the | ||||
| function and the optional `opts` argument in more detail. | ||||
| 
 | ||||
| _Generate a list of formulae from a single worksheet_ | ||||
| 
 | ||||
| ```js | ||||
| var fmla = XLSX.utils.sheet_to_formulae(worksheet); | ||||
| ``` | ||||
| 
 | ||||
| This snapshot generates an array of entries representing the embedded formulae. | ||||
| Array formulae are rendered in the form `range=formula` while plain cells are | ||||
| rendered in the form `cell=formula or value`.  String literals are prefixed with | ||||
| an apostrophe `'`, consistent with Excel's formula bar display. | ||||
| 
 | ||||
| ["Formulae Output"](../api/utilities#formulae-output) describes the function in more detail. | ||||
							
								
								
									
										4
									
								
								docz/docs/06-solutions/_category_.json
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,4 @@ | ||||
| { | ||||
|   "label": "Common Use Cases", | ||||
|   "position": 6 | ||||
| } | ||||
							
								
								
									
										150
									
								
								docz/docs/07-csf/01-general.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,150 @@ | ||||
| --- | ||||
| sidebar_position: 1 | ||||
| --- | ||||
| 
 | ||||
| # Core Concepts | ||||
| 
 | ||||
| The "Common Spreadsheet Format" (CSF) is the object model used by SheetJS. | ||||
| 
 | ||||
| ## Cell Addresses and Ranges | ||||
| 
 | ||||
| Cell address objects are stored as `{c:C, r:R}` where `C` and `R` are 0-indexed | ||||
| column and row numbers, respectively.  For example, the cell address `B5` is | ||||
| represented by the object `{c:1, r:4}`. | ||||
| 
 | ||||
| Cell range objects are stored as `{s:S, e:E}` where `S` is the first cell and | ||||
| `E` is the last cell in the range.  The ranges are inclusive.  For example, the | ||||
| range `A3:B7` is represented by the object `{s:{c:0, r:2}, e:{c:1, r:6}}`. | ||||
| Utility functions perform a row-major order walk traversal of a sheet range: | ||||
| 
 | ||||
| ```js | ||||
| for(var R = range.s.r; R <= range.e.r; ++R) { | ||||
|   for(var C = range.s.c; C <= range.e.c; ++C) { | ||||
|     var cell_address = {c:C, r:R}; | ||||
|     /* if an A1-style address is needed, encode the address */ | ||||
|     var cell_ref = XLSX.utils.encode_cell(cell_address); | ||||
|   } | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| ## Cell Object | ||||
| 
 | ||||
| Cell objects are plain JS objects with keys and values following the convention: | ||||
| 
 | ||||
| | Key | Description                                                            | | ||||
| | --- | ---------------------------------------------------------------------- | | ||||
| | `v` | raw value (see [Data Types](#data-types) section for more info)        | | ||||
| | `w` | formatted text (if applicable)                                         | | ||||
| | `t` | type: `b` Boolean, `e` Error, `n` Number, `d` Date, `s` Text, `z` Stub | | ||||
| | `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)                      | | ||||
| | `r` | rich text encoding (if applicable)                                     | | ||||
| | `h` | HTML rendering of the rich text (if applicable)                        | | ||||
| | `c` | comments associated with the cell                                      | | ||||
| | `z` | number format string associated with the cell (if requested)           | | ||||
| | `l` | cell hyperlink object (`.Target` holds link, `.Tooltip` is tooltip)    | | ||||
| | `s` | the style/theme of the cell (if applicable)                            | | ||||
| 
 | ||||
| Built-in export utilities (such as the CSV exporter) will use the `w` text if it | ||||
| is available.  To change a value, be sure to delete `cell.w` (or set it to | ||||
| `undefined`) before attempting to export.  The utilities will regenerate the `w` | ||||
| text from the number format (`cell.z`) and the raw value if possible. | ||||
| 
 | ||||
| The actual array formula is stored in the `f` field of the first cell in the | ||||
| array range.  Other cells in the range will omit the `f` field. | ||||
| 
 | ||||
| ### Data Types | ||||
| 
 | ||||
| The raw value is stored in the `v` value property, interpreted based on the `t` | ||||
| type property.  This separation allows for representation of numbers as well as | ||||
| numeric text.  There are 6 valid cell types: | ||||
| 
 | ||||
| | Type | Description                                                           | | ||||
| | :--: | :-------------------------------------------------------------------- | | ||||
| | `b`  | Boolean: value interpreted as JS `boolean`                            | | ||||
| | `e`  | Error: value is a numeric code and `w` property stores common name ** | | ||||
| | `n`  | Number: value is a JS `number` **                                     | | ||||
| | `d`  | Date: value is a JS `Date` object or string to be parsed as Date **   | | ||||
| | `s`  | Text: value interpreted as JS `string` and written as text **         | | ||||
| | `z`  | Stub: blank stub cell that is ignored by data processing utilities ** | | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Error values and interpretation</b> (click to show)</summary> | ||||
| 
 | ||||
| |  Value | Error Meaning   | | ||||
| | -----: | :-------------- | | ||||
| | `0x00` | `#NULL!`        | | ||||
| | `0x07` | `#DIV/0!`       | | ||||
| | `0x0F` | `#VALUE!`       | | ||||
| | `0x17` | `#REF!`         | | ||||
| | `0x1D` | `#NAME?`        | | ||||
| | `0x24` | `#NUM!`         | | ||||
| | `0x2A` | `#N/A`          | | ||||
| | `0x2B` | `#GETTING_DATA` | | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| Type `n` is the Number type. This includes all forms of data that Excel stores | ||||
| as numbers, such as dates/times and Boolean fields.  Excel exclusively uses data | ||||
| that can be fit in an IEEE754 floating point number, just like JS Number, so the | ||||
| `v` field holds the raw number.  The `w` field holds formatted text.  Dates are | ||||
| stored as numbers by default and converted with `XLSX.SSF.parse_date_code`. | ||||
| 
 | ||||
| Type `d` is the Date type, generated only when the option `cellDates` is passed. | ||||
| Since JSON does not have a natural Date type, parsers are generally expected to | ||||
| store ISO 8601 Date strings like you would get from `date.toISOString()`.  On | ||||
| the other hand, writers and exporters should be able to handle date strings and | ||||
| JS Date objects.  Note that Excel disregards timezone modifiers and treats all | ||||
| dates in the local timezone.  The library does not correct for this error. | ||||
| 
 | ||||
| Type `s` is the String type.  Values are explicitly stored as text.  Excel will | ||||
| interpret these cells as "number stored as text".  Generated Excel files | ||||
| automatically suppress that class of error, but other formats may elicit errors. | ||||
| 
 | ||||
| Type `z` represents blank stub cells.  They are generated in cases where cells | ||||
| have no assigned value but hold comments or other metadata. They are ignored by | ||||
| the core library data processing utility functions.  By default these cells are | ||||
| not generated; the parser `sheetStubs` option must be set to `true`. | ||||
| 
 | ||||
| 
 | ||||
| #### Dates | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Excel Date Code details</b> (click to show)</summary> | ||||
| 
 | ||||
| By default, Excel stores dates as numbers with a format code that specifies date | ||||
| processing.  For example, the date `19-Feb-17` is stored as the number `42785` | ||||
| with a number format of `d-mmm-yy`.  The `SSF` module understands number formats | ||||
| and performs the appropriate conversion. | ||||
| 
 | ||||
| XLSX also supports a special date type `d` where the data is an ISO 8601 date | ||||
| string.  The formatter converts the date back to a number. | ||||
| 
 | ||||
| The default behavior for all parsers is to generate number cells.  Setting | ||||
| `cellDates` to true will force the generators to store dates. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Time Zones and Dates</b> (click to show)</summary> | ||||
| 
 | ||||
| Excel has no native concept of universal time.  All times are specified in the | ||||
| local time zone.  Excel limitations prevent specifying true absolute dates. | ||||
| 
 | ||||
| Following Excel, this library treats all dates as relative to local time zone. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Epochs: 1900 and 1904</b> (click to show)</summary> | ||||
| 
 | ||||
| Excel supports two epochs (January 1 1900 and January 1 1904). | ||||
| The workbook's epoch can be determined by examining the workbook's | ||||
| `wb.Workbook.WBProps.date1904` property: | ||||
| 
 | ||||
| ```js | ||||
| !!(((wb.Workbook||{}).WBProps||{}).date1904) | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
							
								
								
									
										144
									
								
								docz/docs/07-csf/02-sheet.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,144 @@ | ||||
| --- | ||||
| sidebar_position: 2 | ||||
| --- | ||||
| 
 | ||||
| # Sheet Objects | ||||
| 
 | ||||
| Excel supports 4 different types of "sheets": | ||||
| - "worksheets": normal sheets | ||||
| - "chartsheets": full-tab charts | ||||
| - "macrosheets": legacy (pre-VBA) macros | ||||
| - "dialogsheets": legacy (pre-VBA) dialogs | ||||
| 
 | ||||
| ## Generic Sheet Object | ||||
| 
 | ||||
| Generic sheets are plain JavaScript objects.  Each key that does not start with | ||||
| `!` is an `A1`-style address whose corresponding value is a cell object. | ||||
| 
 | ||||
| `sheet[address]` returns the cell object for the specified address. | ||||
| 
 | ||||
| ### Sheet Properties | ||||
| 
 | ||||
| Each key starts with `!`.  The properties are accessible as `sheet[key]`. | ||||
| 
 | ||||
| - `sheet['!ref']`: A-1 based range representing the sheet range. Functions that | ||||
|   work with sheets should use this parameter to determine the range.  Cells that | ||||
|   are assigned outside of the range are not processed.  In particular, when | ||||
|   writing a sheet by hand, cells outside of the range are not included | ||||
| 
 | ||||
|   Functions that handle sheets should test for the presence of `!ref` field. | ||||
|   If the `!ref` is omitted or is not a valid range, functions are free to treat | ||||
|   the sheet as empty or attempt to guess the range.  The standard utilities that | ||||
|   ship with this library treat sheets as empty (for example, the CSV output is | ||||
|   empty string). | ||||
| 
 | ||||
|   When reading a worksheet with the `sheetRows` property set, the ref parameter | ||||
|   will use the restricted range.  The original range is set at `ws['!fullref']` | ||||
| 
 | ||||
| - `sheet['!margins']`: Object representing the page margins.  The default values | ||||
|   follow Excel's "normal" preset.  Excel also has a "wide" and a "narrow" preset | ||||
|   but they are stored as raw measurements. The main properties are listed below: | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Page margin details</b> (click to show)</summary> | ||||
| 
 | ||||
| | key      | description            | "normal" | "wide" | "narrow" | | ||||
| |----------|------------------------|:---------|:-------|:-------- | | ||||
| | `left`   | left margin (inches)   | `0.7`    | `1.0`  | `0.25`   | | ||||
| | `right`  | right margin (inches)  | `0.7`    | `1.0`  | `0.25`   | | ||||
| | `top`    | top margin (inches)    | `0.75`   | `1.0`  | `0.75`   | | ||||
| | `bottom` | bottom margin (inches) | `0.75`   | `1.0`  | `0.75`   | | ||||
| | `header` | header margin (inches) | `0.3`    | `0.5`  | `0.3`    | | ||||
| | `footer` | footer margin (inches) | `0.3`    | `0.5`  | `0.3`    | | ||||
| 
 | ||||
| ```js | ||||
| /* Set worksheet sheet to "normal" */ | ||||
| ws["!margins"]={left:0.7, right:0.7, top:0.75,bottom:0.75,header:0.3,footer:0.3} | ||||
| /* Set worksheet sheet to "wide" */ | ||||
| ws["!margins"]={left:1.0, right:1.0, top:1.0, bottom:1.0, header:0.5,footer:0.5} | ||||
| /* Set worksheet sheet to "narrow" */ | ||||
| ws["!margins"]={left:0.25,right:0.25,top:0.75,bottom:0.75,header:0.3,footer:0.3} | ||||
| ``` | ||||
| </details> | ||||
| 
 | ||||
| ## Worksheet Object | ||||
| 
 | ||||
| In addition to the aforementioned sheet keys, worksheets also add: | ||||
| 
 | ||||
| - `ws['!cols']`: array of column properties objects.  Column widths are actually | ||||
|   stored in files in a normalized manner, measured in terms of the "Maximum | ||||
|   Digit Width" (the largest width of the rendered digits 0-9, in pixels).  When | ||||
|   parsed, the column objects store the pixel width in the `wpx` field, character | ||||
|   width in the `wch` field, and the maximum digit width in the `MDW` field. | ||||
| 
 | ||||
| - `ws['!rows']`: array of row properties objects as explained later in the docs. | ||||
|   Each row object encodes properties including row height and visibility. | ||||
| 
 | ||||
| - `ws['!merges']`: array of range objects corresponding to the merged cells in | ||||
|   the worksheet.  Plain text formats do not support merge cells.  CSV export | ||||
|   will write all cells in the merge range if they exist, so be sure that only | ||||
|   the first cell (upper-left) in the range is set. | ||||
| 
 | ||||
| - `ws['!outline']`: configure how outlines should behave.  Options default to | ||||
|   the default settings in Excel 2019: | ||||
| 
 | ||||
| | key       | Excel feature                                 | default | | ||||
| |:----------|:----------------------------------------------|:--------| | ||||
| | `above`   | Uncheck "Summary rows below detail"           | `false` | | ||||
| | `left`    | Uncheck "Summary rows to the right of detail" | `false` | | ||||
| 
 | ||||
| - `ws['!protect']`: object of write sheet protection properties.  The `password` | ||||
|   key specifies the password for formats that support password-protected sheets | ||||
|   (XLSX/XLSB/XLS).  The writer uses the XOR obfuscation method.  The following | ||||
|   keys control the sheet protection -- set to `false` to enable a feature when | ||||
|   sheet is locked or set to `true` to disable a feature: | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Worksheet Protection Details</b> (click to show)</summary> | ||||
| 
 | ||||
| | key                   | feature (true=disabled / false=enabled) | default    | | ||||
| |:----------------------|:----------------------------------------|:-----------| | ||||
| | `selectLockedCells`   | Select locked cells                     | enabled    | | ||||
| | `selectUnlockedCells` | Select unlocked cells                   | enabled    | | ||||
| | `formatCells`         | Format cells                            | disabled   | | ||||
| | `formatColumns`       | Format columns                          | disabled   | | ||||
| | `formatRows`          | Format rows                             | disabled   | | ||||
| | `insertColumns`       | Insert columns                          | disabled   | | ||||
| | `insertRows`          | Insert rows                             | disabled   | | ||||
| | `insertHyperlinks`    | Insert hyperlinks                       | disabled   | | ||||
| | `deleteColumns`       | Delete columns                          | disabled   | | ||||
| | `deleteRows`          | Delete rows                             | disabled   | | ||||
| | `sort`                | Sort                                    | disabled   | | ||||
| | `autoFilter`          | Filter                                  | disabled   | | ||||
| | `pivotTables`         | Use PivotTable reports                  | disabled   | | ||||
| | `objects`             | Edit objects                            | enabled    | | ||||
| | `scenarios`           | Edit scenarios                          | enabled    | | ||||
| </details> | ||||
| 
 | ||||
| - `ws['!autofilter']`: AutoFilter object following the schema: | ||||
| 
 | ||||
| ```typescript | ||||
| type AutoFilter = { | ||||
|   ref:string; // A-1 based range representing the AutoFilter table range | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| ## Other Sheet Types | ||||
| 
 | ||||
| ### Chartsheet Object | ||||
| 
 | ||||
| Chartsheets are represented as standard sheets.  They are distinguished with the | ||||
| `!type` property set to `"chart"`. | ||||
| 
 | ||||
| The underlying data and `!ref` refer to the cached data in the chartsheet.  The | ||||
| first row of the chartsheet is the underlying header. | ||||
| 
 | ||||
| ### Macrosheet Object | ||||
| 
 | ||||
| Macrosheets are represented as standard sheets.  They are distinguished with the | ||||
| `!type` property set to `"macro"`. | ||||
| 
 | ||||
| ### Dialogsheet Object | ||||
| 
 | ||||
| Dialogsheets are represented as standard sheets. They are distinguished with the | ||||
| `!type` property set to `"dialog"`. | ||||
							
								
								
									
										107
									
								
								docz/docs/07-csf/03-book.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,107 @@ | ||||
| --- | ||||
| sidebar_position: 3 | ||||
| --- | ||||
| 
 | ||||
| # Workbook Object | ||||
| 
 | ||||
| `workbook.SheetNames` is an ordered list of the sheets in the workbook | ||||
| 
 | ||||
| `wb.Sheets[sheetname]` returns an object representing the worksheet. | ||||
| 
 | ||||
| `wb.Props` is an object storing the standard properties.  `wb.Custprops` stores | ||||
| custom properties.  Since the XLS standard properties deviate from the XLSX | ||||
| standard, XLS parsing stores core properties in both places. | ||||
| 
 | ||||
| `wb.Workbook` stores [workbook-level attributes](#workbook-level-attributes). | ||||
| 
 | ||||
| ## File Properties | ||||
| 
 | ||||
| The various file formats use different internal names for file properties.  The | ||||
| workbook `Props` object normalizes the names: | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>File Properties</b> (click to show)</summary> | ||||
| 
 | ||||
| | JS Name       | Excel Description              | | ||||
| |:--------------|:-------------------------------| | ||||
| | `Title`       | Summary tab "Title"            | | ||||
| | `Subject`     | Summary tab "Subject"          | | ||||
| | `Author`      | Summary tab "Author"           | | ||||
| | `Manager`     | Summary tab "Manager"          | | ||||
| | `Company`     | Summary tab "Company"          | | ||||
| | `Category`    | Summary tab "Category"         | | ||||
| | `Keywords`    | Summary tab "Keywords"         | | ||||
| | `Comments`    | Summary tab "Comments"         | | ||||
| | `LastAuthor`  | Statistics tab "Last saved by" | | ||||
| | `CreatedDate` | Statistics tab "Created"       | | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| For example, to set the workbook title property: | ||||
| 
 | ||||
| ```js | ||||
| if(!wb.Props) wb.Props = {}; | ||||
| wb.Props.Title = "Insert Title Here"; | ||||
| ``` | ||||
| 
 | ||||
| Custom properties are added in the workbook `Custprops` object: | ||||
| 
 | ||||
| ```js | ||||
| if(!wb.Custprops) wb.Custprops = {}; | ||||
| wb.Custprops["Custom Property"] = "Custom Value"; | ||||
| ``` | ||||
| 
 | ||||
| Writers will process the `Props` key of the options object: | ||||
| 
 | ||||
| ```js | ||||
| /* force the Author to be "SheetJS" */ | ||||
| XLSX.write(wb, {Props:{Author:"SheetJS"}}); | ||||
| ``` | ||||
| 
 | ||||
| ## Workbook-Level Attributes | ||||
| 
 | ||||
| `wb.Workbook` stores workbook-level attributes. | ||||
| 
 | ||||
| ### Defined Names | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Format Support</b> (click to show)</summary> | ||||
| 
 | ||||
| **Defined Names**: XLSX/M, XLSB, BIFF8 XLS, XLML, SYLK | ||||
| 
 | ||||
| **Unicode Defined Names**: XLSX/M, XLSB, BIFF8 XLS, XLML | ||||
| 
 | ||||
| **Defined Name Comment**: XLSX/M, XLSB, BIFF8 XLS | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| `wb.Workbook.Names` is an array of defined name objects which have the keys: | ||||
| 
 | ||||
| | Key       | Description                                                      | | ||||
| |:----------|:-----------------------------------------------------------------| | ||||
| | `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"`)                       | | ||||
| | `Comment` | Comment (only applicable for XLS/XLSX/XLSB)                      | | ||||
| 
 | ||||
| Excel allows two sheet-scoped defined names to share the same name.  However, a | ||||
| sheet-scoped name cannot collide with a workbook-scope name.  Workbook writers | ||||
| may not enforce this constraint. | ||||
| 
 | ||||
| ### Workbook Views | ||||
| 
 | ||||
| `wb.Workbook.Views` is an array of workbook view objects which have the keys: | ||||
| 
 | ||||
| | Key             | Description                                         | | ||||
| |:----------------|:----------------------------------------------------| | ||||
| | `RTL`           | If true, display right-to-left                      | | ||||
| 
 | ||||
| ### Miscellaneous Workbook Properties | ||||
| 
 | ||||
| `wb.Workbook.WBProps` holds other workbook properties: | ||||
| 
 | ||||
| | Key             | Description                                         | | ||||
| |:----------------|:----------------------------------------------------| | ||||
| | `CodeName`      | [VBA Workbook Code Name](./features#vba-and-macros) | | ||||
| | `date1904`      | epoch: 0/false for 1900 system, 1/true for 1904     | | ||||
| | `filterPrivacy` | Warn or strip personally identifying info on save   | | ||||
							
								
								
									
										701
									
								
								docz/docs/07-csf/07-features.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,701 @@ | ||||
| --- | ||||
| sidebar_position: 7 | ||||
| --- | ||||
| 
 | ||||
| # Spreadsheet Features | ||||
| 
 | ||||
| Even for basic features like date storage, the official Excel formats store the | ||||
| same content in different ways.  The parsers are expected to convert from the | ||||
| underlying file format representation to the Common Spreadsheet Format.  Writers | ||||
| are expected to convert from CSF back to the underlying file format. | ||||
| 
 | ||||
| ## Formulae | ||||
| 
 | ||||
| The A1-style formula string is stored in the `f` field.  Even though different | ||||
| file formats store the formulae in different ways, the formats are translated. | ||||
| Even though some formats store formulae with a leading equal sign, CSF formulae | ||||
| do not start with `=`. | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Formulae File Format Support</b> (click to show)</summary> | ||||
| 
 | ||||
| | Storage Representation | Formats                  | Read  | Write | | ||||
| |:-----------------------|:-------------------------|:-----:|:-----:| | ||||
| | A1-style strings       | XLSX                     |   ✔   |   ✔   | | ||||
| | RC-style strings       | XLML and plain text      |   ✔   |   ✔   | | ||||
| | BIFF Parsed formulae   | XLSB and all XLS formats |   ✔   |       | | ||||
| | OpenFormula formulae   | ODS/FODS/UOS             |   ✔   |   ✔   | | ||||
| | Lotus Parsed formulae  | All Lotus WK_ formats    |   ✔   |       | | ||||
| 
 | ||||
| Since Excel prohibits named cells from colliding with names of A1 or RC style | ||||
| cell references, a (not-so-simple) regex conversion is possible.  BIFF Parsed | ||||
| formulae and Lotus Parsed formulae have to be explicitly unwound.  OpenFormula | ||||
| formulae can be converted with regular expressions. | ||||
| 
 | ||||
| Shared formulae are decompressed and each cell has the formula corresponding to | ||||
| its cell.  Writers generally do not attempt to generate shared formulae. | ||||
| </details> | ||||
| 
 | ||||
| ### Single-Cell Formulae | ||||
| 
 | ||||
| For simple formulae, the `f` key of the desired cell can be set to the actual | ||||
| formula text.  This worksheet represents `A1=1`, `A2=2`, and `A3=A1+A2`: | ||||
| 
 | ||||
| ```js | ||||
| var worksheet = { | ||||
|   "!ref": "A1:A3", | ||||
|   A1: { t:'n', v:1 }, | ||||
|   A2: { t:'n', v:2 }, | ||||
|   A3: { t:'n', v:3, f:'A1+A2' } | ||||
| }; | ||||
| ``` | ||||
| 
 | ||||
| Utilities like `aoa_to_sheet` will accept cell objects in lieu of values: | ||||
| 
 | ||||
| ```js | ||||
| var worksheet = XLSX.utils.aoa_to_sheet([ | ||||
|   [ 1 ], // A1 | ||||
|   [ 2 ], // A2 | ||||
|   [ {t: "n", v: 3, f: "A1+A2"} ] // A3 | ||||
| ]); | ||||
| ``` | ||||
| 
 | ||||
| Cells with formula entries but no value will be serialized in a way that Excel | ||||
| and other spreadsheet tools will recognize.  This library will not automatically | ||||
| compute formula results!  For example, the following worksheet will include the | ||||
| `BESSELJ` function but the result will not be available in JavaScript: | ||||
| 
 | ||||
| ```js | ||||
| var worksheet = XLSX.utils.aoa_to_sheet([ | ||||
|   [ 3.14159, 2 ], // Row "1" | ||||
|   [ { t:'n', f:'BESSELJ(A1,B1)' } ] // Row "2" will be calculated on file open | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| If the actual results are needed in JS, [SheetJS Pro](https://sheetjs.com/pro) | ||||
| offers a formula calculator component for evaluating expressions, updating | ||||
| values and dependent cells, and refreshing entire workbooks. | ||||
| 
 | ||||
| 
 | ||||
| ### Array Formulae | ||||
| 
 | ||||
| _Assign an array formula_ | ||||
| 
 | ||||
| ```js | ||||
| XLSX.utils.sheet_set_array_formula(worksheet, range, formula); | ||||
| ``` | ||||
| 
 | ||||
| Array formulae are stored in the top-left cell of the array block.  All cells | ||||
| of an array formula have a `F` field corresponding to the range.  A single-cell | ||||
| formula can be distinguished from a plain formula by the presence of `F` field. | ||||
| 
 | ||||
| For example, setting the cell `C1` to the array formula `{=SUM(A1:A3*B1:B3)}`: | ||||
| 
 | ||||
| ```js | ||||
| // API function | ||||
| XLSX.utils.sheet_set_array_formula(worksheet, "C1", "SUM(A1:A3*B1:B3)"); | ||||
| 
 | ||||
| // ... OR raw operations | ||||
| worksheet['C1'] = { t:'n', f: "SUM(A1:A3*B1:B3)", F:"C1:C1" }; | ||||
| ``` | ||||
| 
 | ||||
| For a multi-cell array formula, every cell has the same array range but only the | ||||
| first cell specifies the formula.  Consider `D1:D3=A1:A3*B1:B3`: | ||||
| 
 | ||||
| ```js | ||||
| // API function | ||||
| XLSX.utils.sheet_set_array_formula(worksheet, "D1:D3", "A1:A3*B1:B3"); | ||||
| 
 | ||||
| // ... OR raw operations | ||||
| worksheet['D1'] = { t:'n', F:"D1:D3", f:"A1:A3*B1:B3" }; | ||||
| worksheet['D2'] = { t:'n', F:"D1:D3" }; | ||||
| worksheet['D3'] = { t:'n', F:"D1:D3" }; | ||||
| ``` | ||||
| 
 | ||||
| Utilities and writers are expected to check for the presence of a `F` field and | ||||
| ignore any possible formula element `f` in cells other than the starting cell. | ||||
| They are not expected to perform validation of the formulae! | ||||
| 
 | ||||
| 
 | ||||
| ### Dynamic Arrays | ||||
| 
 | ||||
| _Assign a dynamic array formula_ | ||||
| 
 | ||||
| ```js | ||||
| XLSX.utils.sheet_set_array_formula(worksheet, range, formula, true); | ||||
| ``` | ||||
| 
 | ||||
| Released in 2020, Dynamic Array Formulae are supported in the XLSX/XLSM and XLSB | ||||
| file formats.  They are represented like normal array formulae but have special | ||||
| cell metadata indicating that the formula should be allowed to adjust the range. | ||||
| 
 | ||||
| An array formula can be marked as dynamic by setting the cell's `D` property to | ||||
| true.  The `F` range is expected but can be the set to the current cell: | ||||
| 
 | ||||
| ```js | ||||
| // API function | ||||
| XLSX.utils.sheet_set_array_formula(worksheet, "C1", "_xlfn.UNIQUE(A1:A3)", 1); | ||||
| 
 | ||||
| // ... OR raw operations | ||||
| worksheet['C1'] = { t: "s", f: "_xlfn.UNIQUE(A1:A3)", F:"C1", D: 1 }; // dynamic | ||||
| ``` | ||||
| 
 | ||||
| ### Localization | ||||
| 
 | ||||
| SheetJS operates at the file level.  Excel stores formula expressions using the | ||||
| English (United States) function names.  For non-English users, Excel uses a | ||||
| localized set of function names. | ||||
| 
 | ||||
| For example, when the computer language and region is set to French (France), | ||||
| Excel interprets `=SOMME(A1:C3)` as if `SOMME` is the `SUM` function.  However, | ||||
| in the actual file, Excel stores `SUM(A1:C3)`. | ||||
| 
 | ||||
| **Prefixed "Future Functions"** | ||||
| 
 | ||||
| Functions introduced in newer versions of Excel are prefixed with `_xlfn.` when | ||||
| stored in files.  When writing formula expressions using these functions, the | ||||
| prefix is required for maximal compatibility: | ||||
| 
 | ||||
| ```js | ||||
| // Broadest compatibility | ||||
| XLSX.utils.sheet_set_array_formula(worksheet, "C1", "_xlfn.UNIQUE(A1:A3)", 1); | ||||
| 
 | ||||
| // Can cause errors in spreadsheet software | ||||
| XLSX.utils.sheet_set_array_formula(worksheet, "C1", "UNIQUE(A1:A3)", 1); | ||||
| ``` | ||||
| 
 | ||||
| When reading a file, the `xlfn` option preserves the prefixes. | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b> Functions requiring `_xlfn.` prefix</b> (click to show)</summary> | ||||
| 
 | ||||
| This list is growing with each Excel release. | ||||
| 
 | ||||
| ``` | ||||
| ACOT | ||||
| ACOTH | ||||
| AGGREGATE | ||||
| ARABIC | ||||
| BASE | ||||
| BETA.DIST | ||||
| BETA.INV | ||||
| BINOM.DIST | ||||
| BINOM.DIST.RANGE | ||||
| BINOM.INV | ||||
| BITAND | ||||
| BITLSHIFT | ||||
| BITOR | ||||
| BITRSHIFT | ||||
| BITXOR | ||||
| BYCOL | ||||
| BYROW | ||||
| CEILING.MATH | ||||
| CEILING.PRECISE | ||||
| CHISQ.DIST | ||||
| CHISQ.DIST.RT | ||||
| CHISQ.INV | ||||
| CHISQ.INV.RT | ||||
| CHISQ.TEST | ||||
| COMBINA | ||||
| CONFIDENCE.NORM | ||||
| CONFIDENCE.T | ||||
| COT | ||||
| COTH | ||||
| COVARIANCE.P | ||||
| COVARIANCE.S | ||||
| CSC | ||||
| CSCH | ||||
| DAYS | ||||
| DECIMAL | ||||
| ERF.PRECISE | ||||
| ERFC.PRECISE | ||||
| EXPON.DIST | ||||
| F.DIST | ||||
| F.DIST.RT | ||||
| F.INV | ||||
| F.INV.RT | ||||
| F.TEST | ||||
| FIELDVALUE | ||||
| FILTERXML | ||||
| FLOOR.MATH | ||||
| FLOOR.PRECISE | ||||
| FORMULATEXT | ||||
| GAMMA | ||||
| GAMMA.DIST | ||||
| GAMMA.INV | ||||
| GAMMALN.PRECISE | ||||
| GAUSS | ||||
| HYPGEOM.DIST | ||||
| IFNA | ||||
| IMCOSH | ||||
| IMCOT | ||||
| IMCSC | ||||
| IMCSCH | ||||
| IMSEC | ||||
| IMSECH | ||||
| IMSINH | ||||
| IMTAN | ||||
| ISFORMULA | ||||
| ISOMITTED | ||||
| ISOWEEKNUM | ||||
| LAMBDA | ||||
| LET | ||||
| LOGNORM.DIST | ||||
| LOGNORM.INV | ||||
| MAKEARRAY | ||||
| MAP | ||||
| MODE.MULT | ||||
| MODE.SNGL | ||||
| MUNIT | ||||
| NEGBINOM.DIST | ||||
| NORM.DIST | ||||
| NORM.INV | ||||
| NORM.S.DIST | ||||
| NORM.S.INV | ||||
| NUMBERVALUE | ||||
| PDURATION | ||||
| PERCENTILE.EXC | ||||
| PERCENTILE.INC | ||||
| PERCENTRANK.EXC | ||||
| PERCENTRANK.INC | ||||
| PERMUTATIONA | ||||
| PHI | ||||
| POISSON.DIST | ||||
| QUARTILE.EXC | ||||
| QUARTILE.INC | ||||
| QUERYSTRING | ||||
| RANDARRAY | ||||
| RANK.AVG | ||||
| RANK.EQ | ||||
| REDUCE | ||||
| RRI | ||||
| SCAN | ||||
| SEC | ||||
| SECH | ||||
| SEQUENCE | ||||
| SHEET | ||||
| SHEETS | ||||
| SKEW.P | ||||
| SORTBY | ||||
| STDEV.P | ||||
| STDEV.S | ||||
| T.DIST | ||||
| T.DIST.2T | ||||
| T.DIST.RT | ||||
| T.INV | ||||
| T.INV.2T | ||||
| T.TEST | ||||
| UNICHAR | ||||
| UNICODE | ||||
| UNIQUE | ||||
| VAR.P | ||||
| VAR.S | ||||
| WEBSERVICE | ||||
| WEIBULL.DIST | ||||
| XLOOKUP | ||||
| XOR | ||||
| Z.TEST | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ## Row and Column Properties | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Format Support</b> (click to show)</summary> | ||||
| 
 | ||||
| **Row Properties**: XLSX/M, XLSB, BIFF8 XLS, XLML, SYLK, DOM, ODS | ||||
| 
 | ||||
| **Column Properties**: XLSX/M, XLSB, BIFF8 XLS, XLML, SYLK, DOM | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| 
 | ||||
| Row and Column properties are not extracted by default when reading from a file | ||||
| and are not persisted by default when writing to a file. The option | ||||
| `cellStyles: true` must be passed to the relevant read or write function. | ||||
| 
 | ||||
| _Column Properties_ | ||||
| 
 | ||||
| The `!cols` array in each worksheet, if present, is a collection of `ColInfo` | ||||
| objects which have the following properties: | ||||
| 
 | ||||
| ```typescript | ||||
| type ColInfo = { | ||||
|   /* visibility */ | ||||
|   hidden?: boolean; // if true, the column is hidden | ||||
| 
 | ||||
|   /* column width is specified in one of the following ways: */ | ||||
|   wpx?:    number;  // width in screen pixels | ||||
|   width?:  number;  // width in Excel's "Max Digit Width", width*256 is integral | ||||
|   wch?:    number;  // width in characters | ||||
| 
 | ||||
|   /* other fields for preserving features from files */ | ||||
|   level?:  number;  // 0-indexed outline / group level | ||||
|   MDW?:    number;  // Excel's "Max Digit Width" unit, always integral | ||||
| }; | ||||
| ``` | ||||
| 
 | ||||
| _Row Properties_ | ||||
| 
 | ||||
| The `!rows` array in each worksheet, if present, is a collection of `RowInfo` | ||||
| objects which have the following properties: | ||||
| 
 | ||||
| ```typescript | ||||
| type RowInfo = { | ||||
|   /* visibility */ | ||||
|   hidden?: boolean; // if true, the row is hidden | ||||
| 
 | ||||
|   /* row height is specified in one of the following ways: */ | ||||
|   hpx?:    number;  // height in screen pixels | ||||
|   hpt?:    number;  // height in points | ||||
| 
 | ||||
|   level?:  number;  // 0-indexed outline / group level | ||||
| }; | ||||
| ``` | ||||
| 
 | ||||
| _Outline / Group Levels Convention_ | ||||
| 
 | ||||
| The Excel UI displays the base outline level as `1` and the max level as `8`. | ||||
| Following JS conventions, SheetJS uses 0-indexed outline levels wherein the base | ||||
| outline level is `0` and the max level is `7`. | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Why are there three width types?</b> (click to show)</summary> | ||||
| 
 | ||||
| There are three different width types corresponding to the three different ways | ||||
| spreadsheets store column widths: | ||||
| 
 | ||||
| SYLK and other plain text formats use raw character count. Contemporaneous tools | ||||
| like Visicalc and Multiplan were character based.  Since the characters had the | ||||
| same width, it sufficed to store a count.  This tradition was continued into the | ||||
| BIFF formats. | ||||
| 
 | ||||
| SpreadsheetML (2003) tried to align with HTML by standardizing on screen pixel | ||||
| count throughout the file.  Column widths, row heights, and other measures use | ||||
| pixels.  When the pixel and character counts do not align, Excel rounds values. | ||||
| 
 | ||||
| XLSX internally stores column widths in a nebulous "Max Digit Width" form.  The | ||||
| Max Digit Width is the width of the largest digit when rendered (generally the | ||||
| "0" character is the widest).  The internal width must be an integer multiple of | ||||
| the the width divided by 256.  ECMA-376 describes a formula for converting | ||||
| between pixels and the internal width.  This represents a hybrid approach. | ||||
| 
 | ||||
| Read functions attempt to populate all three properties.  Write functions will | ||||
| try to cycle specified values to the desired type.  In order to avoid potential | ||||
| conflicts, manipulation should delete the other properties first.  For example, | ||||
| when changing the pixel width, delete the `wch` and `width` properties. | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Implementation details</b> (click to show)</summary> | ||||
| 
 | ||||
| _Row Heights_ | ||||
| 
 | ||||
| Excel internally stores row heights in points.  The default resolution is 72 DPI | ||||
| or 96 PPI, so the pixel and point size should agree.  For different resolutions | ||||
| they may not agree, so the library separates the concepts. | ||||
| 
 | ||||
| Even though all of the information is made available, writers are expected to | ||||
| follow the priority order: | ||||
| 
 | ||||
| 1) use `hpx` pixel height if available | ||||
| 2) use `hpt` point height if available | ||||
| 
 | ||||
| _Column Widths_ | ||||
| 
 | ||||
| Given the constraints, it is possible to determine the MDW without actually | ||||
| inspecting the font!  The parsers guess the pixel width by converting from width | ||||
| to pixels and back, repeating for all possible MDW and selecting the MDW that | ||||
| minimizes the error.  XLML actually stores the pixel width, so the guess works | ||||
| in the opposite direction. | ||||
| 
 | ||||
| Even though all of the information is made available, writers are expected to | ||||
| follow the priority order: | ||||
| 
 | ||||
| 1) use `width` field if available | ||||
| 2) use `wpx` pixel width if available | ||||
| 3) use `wch` character count if available | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ## Number Formats | ||||
| 
 | ||||
| The `cell.w` formatted text for each cell is produced from `cell.v` and `cell.z` | ||||
| format.  If the format is not specified, the Excel `General` format is used. | ||||
| The format can either be specified as a string or as an index into the format | ||||
| table.  Parsers are expected to populate `workbook.SSF` with the number format | ||||
| table.  Writers are expected to serialize the table. | ||||
| 
 | ||||
| Custom tools should ensure that the local table has each used format string | ||||
| somewhere in the table.  Excel convention mandates that the custom formats start | ||||
| at index 164.  The following example creates a custom format from scratch: | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>New worksheet with custom format</b> (click to show)</summary> | ||||
| 
 | ||||
| ```js | ||||
| var wb = { | ||||
|   SheetNames: ["Sheet1"], | ||||
|   Sheets: { | ||||
|     Sheet1: { | ||||
|       "!ref":"A1:C1", | ||||
|       A1: { t:"n", v:10000 },                    // <-- General format | ||||
|       B1: { t:"n", v:10000, z: "0%" },           // <-- Builtin format | ||||
|       C1: { t:"n", v:10000, z: "\"T\"\ #0.00" }  // <-- Custom format | ||||
|     } | ||||
|   } | ||||
| } | ||||
| ``` | ||||
| </details> | ||||
| 
 | ||||
| The rules are slightly different from how Excel displays custom number formats. | ||||
| In particular, literal characters must be wrapped in double quotes or preceded | ||||
| by a backslash. For more info, see the Excel documentation article | ||||
| `Create or delete a custom number format` or ECMA-376 18.8.31 (Number Formats) | ||||
| 
 | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Default Number Formats</b> (click to show)</summary> | ||||
| 
 | ||||
| The default formats are listed in ECMA-376 18.8.30: | ||||
| 
 | ||||
| | ID | Format                     | | ||||
| |---:|:---------------------------| | ||||
| |  0 | `General`                  | | ||||
| |  1 | `0`                        | | ||||
| |  2 | `0.00`                     | | ||||
| |  3 | `#,##0`                    | | ||||
| |  4 | `#,##0.00`                 | | ||||
| |  9 | `0%`                       | | ||||
| | 10 | `0.00%`                    | | ||||
| | 11 | `0.00E+00`                 | | ||||
| | 12 | `# ?/?`                    | | ||||
| | 13 | `# ??/??`                  | | ||||
| | 14 | `m/d/yy` (see below)       | | ||||
| | 15 | `d-mmm-yy`                 | | ||||
| | 16 | `d-mmm`                    | | ||||
| | 17 | `mmm-yy`                   | | ||||
| | 18 | `h:mm AM/PM`               | | ||||
| | 19 | `h:mm:ss AM/PM`            | | ||||
| | 20 | `h:mm`                     | | ||||
| | 21 | `h:mm:ss`                  | | ||||
| | 22 | `m/d/yy h:mm`              | | ||||
| | 37 | `#,##0 ;(#,##0)`           | | ||||
| | 38 | `#,##0 ;[Red](#,##0)`      | | ||||
| | 39 | `#,##0.00;(#,##0.00)`      | | ||||
| | 40 | `#,##0.00;[Red](#,##0.00)` | | ||||
| | 45 | `mm:ss`                    | | ||||
| | 46 | `[h]:mm:ss`                | | ||||
| | 47 | `mmss.0`                   | | ||||
| | 48 | `##0.0E+0`                 | | ||||
| | 49 | `@`                        | | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| Format 14 (`m/d/yy`) is localized by Excel: even though the file specifies that | ||||
| number format, it will be drawn differently based on system settings.  It makes | ||||
| sense when the producer and consumer of files are in the same locale, but that | ||||
| is not always the case over the Internet.  To get around this ambiguity, parse | ||||
| functions accept the `dateNF` option to override the interpretation of that | ||||
| specific format string. | ||||
| 
 | ||||
| ## Hyperlinks | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Format Support</b> (click to show)</summary> | ||||
| 
 | ||||
| **Cell Hyperlinks**: XLSX/M, XLSB, BIFF8 XLS, XLML, ODS | ||||
| 
 | ||||
| **Tooltips**: XLSX/M, XLSB, BIFF8 XLS, XLML | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| Hyperlinks are stored in the `l` key of cell objects.  The `Target` field of the | ||||
| hyperlink object is the target of the link, including the URI fragment. Tooltips | ||||
| are stored in the `Tooltip` field and are displayed when you move your mouse | ||||
| over the text. | ||||
| 
 | ||||
| For example, the following snippet creates a link from cell `A3` to | ||||
| <https://sheetjs.com> with the tip `"Find us @ SheetJS.com!"`: | ||||
| 
 | ||||
| ```js | ||||
| ws['A1'].l = { Target:"https://sheetjs.com", Tooltip:"Find us @ SheetJS.com!" }; | ||||
| ``` | ||||
| 
 | ||||
| Note that Excel does not automatically style hyperlinks -- they will generally | ||||
| be displayed as normal text. | ||||
| 
 | ||||
| _Remote Links_ | ||||
| 
 | ||||
| HTTP / HTTPS links can be used directly: | ||||
| 
 | ||||
| ```js | ||||
| ws['A2'].l = { Target:"https://docs.sheetjs.com/#hyperlinks" }; | ||||
| ws['A3'].l = { Target:"http://localhost:7262/yes_localhost_works" }; | ||||
| ``` | ||||
| 
 | ||||
| Excel also supports `mailto` email links with subject line: | ||||
| 
 | ||||
| ```js | ||||
| ws['A4'].l = { Target:"mailto:ignored@dev.null" }; | ||||
| ws['A5'].l = { Target:"mailto:ignored@dev.null?subject=Test Subject" }; | ||||
| ``` | ||||
| 
 | ||||
| _Local Links_ | ||||
| 
 | ||||
| Links to absolute paths should use the `file://` URI scheme: | ||||
| 
 | ||||
| ```js | ||||
| ws['B1'].l = { Target:"file:///SheetJS/t.xlsx" }; /* Link to /SheetJS/t.xlsx */ | ||||
| ws['B2'].l = { Target:"file:///c:/SheetJS.xlsx" }; /* Link to c:\SheetJS.xlsx */ | ||||
| ``` | ||||
| 
 | ||||
| Links to relative paths can be specified without a scheme: | ||||
| 
 | ||||
| ```js | ||||
| ws['B3'].l = { Target:"SheetJS.xlsb" }; /* Link to SheetJS.xlsb */ | ||||
| ws['B4'].l = { Target:"../SheetJS.xlsm" }; /* Link to ../SheetJS.xlsm */ | ||||
| ``` | ||||
| 
 | ||||
| Relative Paths have undefined behavior in the SpreadsheetML 2003 format.  Excel | ||||
| 2019 will treat a `..\` parent mark as two levels up. | ||||
| 
 | ||||
| _Internal Links_ | ||||
| 
 | ||||
| Links where the target is a cell or range or defined name in the same workbook | ||||
| ("Internal Links") are marked with a leading hash character: | ||||
| 
 | ||||
| ```js | ||||
| ws['C1'].l = { Target:"#E2" }; /* Link to cell E2 */ | ||||
| ws['C2'].l = { Target:"#Sheet2!E2" }; /* Link to cell E2 in sheet Sheet2 */ | ||||
| ws['C3'].l = { Target:"#SomeDefinedName" }; /* Link to Defined Name */ | ||||
| ``` | ||||
| 
 | ||||
| ## Cell Comments | ||||
| 
 | ||||
| Cell comments are objects stored in the `c` array of cell objects.  The actual | ||||
| contents of the comment are split into blocks based on the comment author.  The | ||||
| `a` field of each comment object is the author of the comment and the `t` field | ||||
| is the plain text representation. | ||||
| 
 | ||||
| For example, the following snippet appends a cell comment into cell `A1`: | ||||
| 
 | ||||
| ```js | ||||
| if(!ws.A1.c) ws.A1.c = []; | ||||
| ws.A1.c.push({a:"SheetJS", t:"I'm a little comment, short and stout!"}); | ||||
| ``` | ||||
| 
 | ||||
| Note: XLSB enforces a 54 character limit on the Author name.  Names longer than | ||||
| 54 characters may cause issues with other formats. | ||||
| 
 | ||||
| To mark a comment as normally hidden, set the `hidden` property: | ||||
| 
 | ||||
| ```js | ||||
| if(!ws.A1.c) ws.A1.c = []; | ||||
| ws.A1.c.push({a:"SheetJS", t:"This comment is visible"}); | ||||
| 
 | ||||
| if(!ws.A2.c) ws.A2.c = []; | ||||
| ws.A2.c.hidden = true; | ||||
| ws.A2.c.push({a:"SheetJS", t:"This comment will be hidden"}); | ||||
| ``` | ||||
| 
 | ||||
| 
 | ||||
| _Threaded Comments_ | ||||
| 
 | ||||
| Introduced in Excel 365, threaded comments are plain text comment snippets with | ||||
| author metadata and parent references. They are supported in XLSX and XLSB. | ||||
| 
 | ||||
| To mark a comment as threaded, each comment part must have a true `T` property: | ||||
| 
 | ||||
| ```js | ||||
| if(!ws.A1.c) ws.A1.c = []; | ||||
| ws.A1.c.push({a:"SheetJS", t:"This is not threaded"}); | ||||
| 
 | ||||
| if(!ws.A2.c) ws.A2.c = []; | ||||
| ws.A2.c.hidden = true; | ||||
| ws.A2.c.push({a:"SheetJS", t:"This is threaded", T: true}); | ||||
| ws.A2.c.push({a:"JSSheet", t:"This is also threaded", T: true}); | ||||
| ``` | ||||
| 
 | ||||
| There is no Active Directory or Office 365 metadata associated with authors in a thread. | ||||
| 
 | ||||
| ## Sheet Visibility | ||||
| 
 | ||||
| Excel enables hiding sheets in the lower tab bar.  The sheet data is stored in | ||||
| the file but the UI does not readily make it available.  Standard hidden sheets | ||||
| are revealed in the "Unhide" menu.  Excel also has "very hidden" sheets which | ||||
| cannot be revealed in the menu.  It is only accessible in the VB Editor! | ||||
| 
 | ||||
| The visibility setting is stored in the `Hidden` property of sheet props array. | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>More details</b> (click to show)</summary> | ||||
| 
 | ||||
| | Value | Definition  | | ||||
| |:-----:|:------------| | ||||
| |   0   | Visible     | | ||||
| |   1   | Hidden      | | ||||
| |   2   | Very Hidden | | ||||
| 
 | ||||
| With <https://rawgit.com/SheetJS/test_files/HEAD/sheet_visibility.xlsx>: | ||||
| 
 | ||||
| ```js | ||||
| > wb.Workbook.Sheets.map(function(x) { return [x.name, x.Hidden] }) | ||||
| [ [ 'Visible', 0 ], [ 'Hidden', 1 ], [ 'VeryHidden', 2 ] ] | ||||
| ``` | ||||
| 
 | ||||
| Non-Excel formats do not support the Very Hidden state.  The best way to test | ||||
| if a sheet is visible is to check if the `Hidden` property is logical truth: | ||||
| 
 | ||||
| ```js | ||||
| > wb.Workbook.Sheets.map(function(x) { return [x.name, !x.Hidden] }) | ||||
| [ [ 'Visible', true ], [ 'Hidden', false ], [ 'VeryHidden', false ] ] | ||||
| ``` | ||||
| </details> | ||||
| 
 | ||||
| ## VBA and Macros | ||||
| 
 | ||||
| VBA Macros are stored in a special data blob that is exposed in the `vbaraw` | ||||
| property of the workbook object when the `bookVBA` option is `true`.  They are | ||||
| supported in `XLSM`, `XLSB`, and `BIFF8 XLS` formats.  The supported format | ||||
| writers automatically insert the data blobs if it is present in the workbook and | ||||
| associate with the worksheet names. | ||||
| 
 | ||||
| <details> | ||||
| 	<summary><b>Custom Code Names</b> (click to show)</summary> | ||||
| 
 | ||||
| The workbook code name is stored in `wb.Workbook.WBProps.CodeName`.  By default, | ||||
| Excel will write `ThisWorkbook` or a translated phrase like `DieseArbeitsmappe`. | ||||
| Worksheet and Chartsheet code names are in the worksheet properties object at | ||||
| `wb.Workbook.Sheets[i].CodeName`.  Macrosheets and Dialogsheets are ignored. | ||||
| 
 | ||||
| The readers and writers preserve the code names, but they have to be manually | ||||
| set when adding a VBA blob to a different workbook. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
| 	<summary><b>Macrosheets</b> (click to show)</summary> | ||||
| 
 | ||||
| Older versions of Excel also supported a non-VBA "macrosheet" sheet type that | ||||
| stored automation commands.  These are exposed in objects with the `!type` | ||||
| property set to `"macro"`. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
| 	<summary><b>Detecting macros in workbooks</b> (click to show)</summary> | ||||
| 
 | ||||
| The `vbaraw` field will only be set if macros are present, so testing is simple: | ||||
| 
 | ||||
| ```js | ||||
| function wb_has_macro(wb/*:workbook*/)/*:boolean*/ { | ||||
| 	if(!!wb.vbaraw) return true; | ||||
| 	const sheets = wb.SheetNames.map((n) => wb.Sheets[n]); | ||||
| 	return sheets.some((ws) => !!ws && ws['!type']=='macro'); | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
							
								
								
									
										4
									
								
								docz/docs/07-csf/_category_.json
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,4 @@ | ||||
| { | ||||
|   "label": "Common Spreadsheet Format", | ||||
|   "position": 7 | ||||
| } | ||||
							
								
								
									
										155
									
								
								docz/docs/08-api/05-parse-options.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,155 @@ | ||||
| --- | ||||
| sidebar_position: 5 | ||||
| hide_table_of_contents: true | ||||
| title: Reading Files | ||||
| --- | ||||
| 
 | ||||
| # Parsing Options | ||||
| 
 | ||||
| `XLSX.read(data, read_opts)` attempts to parse `data`. | ||||
| 
 | ||||
| `XLSX.readFile(filename, read_opts)` attempts to read `filename` and parse. | ||||
| 
 | ||||
| The read functions accept an options argument: | ||||
| 
 | ||||
| | Option Name | Default | Description                                          | | ||||
| | :---------- | ------: | :--------------------------------------------------- | | ||||
| |`type`       |         | Input data encoding (see Input Type below)           | | ||||
| |`raw`        | false   | If true, plain text parsing will not parse values ** | | ||||
| |`codepage`   |         | If specified, use code page when appropriate **      | | ||||
| |`cellFormula`| true    | Save formulae to the .f field                        | | ||||
| |`cellHTML`   | true    | Parse rich text and save HTML to the `.h` field      | | ||||
| |`cellNF`     | false   | Save number format string to the `.z` field          | | ||||
| |`cellStyles` | false   | Save style/theme info to the `.s` field              | | ||||
| |`cellText`   | true    | Generated formatted text to the `.w` field           | | ||||
| |`cellDates`  | false   | Store dates as type `d` (default is `n`)             | | ||||
| |`dateNF`     |         | If specified, use the string for date code 14 **     | | ||||
| |`sheetStubs` | false   | Create cell objects of type `z` for stub cells       | | ||||
| |`sheetRows`  | 0       | If >0, read the first `sheetRows` rows **            | | ||||
| |`bookDeps`   | false   | If true, parse calculation chains                    | | ||||
| |`bookFiles`  | false   | If true, add raw files to book object **             | | ||||
| |`bookProps`  | false   | If true, only parse enough to get book metadata **   | | ||||
| |`bookSheets` | false   | If true, only parse enough to get the sheet names    | | ||||
| |`bookVBA`    | false   | If true, copy VBA blob to `vbaraw` field **          | | ||||
| |`password`   | ""      | If defined and file is encrypted, use password **    | | ||||
| |`WTF`        | false   | If true, throw errors on unexpected file features ** | | ||||
| |`sheets`     |         | If specified, only parse specified sheets **         | | ||||
| |`PRN`        | false   | If true, allow parsing of PRN files **               | | ||||
| |`xlfn`       | false   | If true, preserve `_xlfn.` prefixes in formulae **   | | ||||
| |`FS`         |         | DSV Field Separator override                         | | ||||
| 
 | ||||
| - Even if `cellNF` is false, formatted text will be generated and saved to `.w` | ||||
| - In some cases, sheets may be parsed even if `bookSheets` is false. | ||||
| - Excel aggressively tries to interpret values from CSV and other plain text. | ||||
|   This leads to surprising behavior! The `raw` option suppresses value parsing. | ||||
| - `bookSheets` and `bookProps` combine to give both sets of information | ||||
| - `Deps` will be an empty object if `bookDeps` is false | ||||
| - `bookFiles` behavior depends on file type: | ||||
|     * `keys` array (paths in the ZIP) for ZIP-based formats | ||||
|     * `files` hash (mapping paths to objects representing the files) for ZIP | ||||
|     * `cfb` object for formats using CFB containers | ||||
| - `sheetRows-1` rows will be generated when looking at the JSON object output | ||||
|   (since the header row is counted as a row when parsing the data) | ||||
| - By default all worksheets are parsed.  `sheets` restricts based on input type: | ||||
|     * number: zero-based index of worksheet to parse (`0` is first worksheet) | ||||
|     * string: name of worksheet to parse (case insensitive) | ||||
|     * array of numbers and strings to select multiple worksheets. | ||||
| - `bookVBA` merely exposes the raw VBA CFB object.  It does not parse the data. | ||||
|   XLSM and XLSB store the VBA CFB object in `xl/vbaProject.bin`. BIFF8 XLS mixes | ||||
|   the VBA entries alongside the core Workbook entry, so the library generates a | ||||
|   new XLSB-compatible blob from the XLS CFB container. | ||||
| - `codepage` is applied to BIFF2 - BIFF5 files without `CodePage` records and to | ||||
|   CSV files without BOM in `type:"binary"`.  BIFF8 XLS always defaults to 1200. | ||||
| - `PRN` affects parsing of text files without a common delimiter character. | ||||
| - Currently only XOR encryption is supported.  Unsupported error will be thrown | ||||
|   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 | ||||
|   errors on single worksheets, allowing you to read from the worksheets that do | ||||
|   parse properly. Setting `WTF:true` forces those errors to be thrown. | ||||
| 
 | ||||
| ### Input Type | ||||
| 
 | ||||
| Strings can be interpreted in multiple ways.  The `type` parameter for `read` | ||||
| tells the library how to parse the data argument: | ||||
| 
 | ||||
| | `type`     | expected input                                                  | | ||||
| |------------|-----------------------------------------------------------------| | ||||
| | `"base64"` | string: Base64 encoding of the file                             | | ||||
| | `"binary"` | string: binary string (byte `n` is `data.charCodeAt(n)`)        | | ||||
| | `"string"` | string: JS string (characters interpreted as UTF8)              | | ||||
| | `"buffer"` | nodejs Buffer                                                   | | ||||
| | `"array"`  | array: array of 8-bit unsigned int (byte `n` is `data[n]`)      | | ||||
| | `"file"`   | string: path of file that will be read (nodejs only)            | | ||||
| 
 | ||||
| ### Guessing File Type | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Implementation Details</b> (click to show)</summary> | ||||
| 
 | ||||
| Excel and other spreadsheet tools read the first few bytes and apply other | ||||
| heuristics to determine a file type.  This enables file type punning: renaming | ||||
| files with the `.xls` extension will tell your computer to use Excel to open the | ||||
| file but Excel will know how to handle it.  This library applies similar logic: | ||||
| 
 | ||||
| | Byte 0 | Raw File Type | Spreadsheet Types                                   | | ||||
| |:-------|:--------------|:----------------------------------------------------| | ||||
| | `0xD0` | CFB Container | BIFF 5/8 or protected XLSX/XLSB or WQ3/QPW or XLR   | | ||||
| | `0x09` | BIFF Stream   | BIFF 2/3/4/5                                        | | ||||
| | `0x3C` | XML/HTML      | SpreadsheetML / Flat ODS / UOS1 / HTML / plain text | | ||||
| | `0x50` | ZIP Archive   | XLSB or XLSX/M or ODS or UOS2 or NUMBERS or text    | | ||||
| | `0x49` | Plain Text    | SYLK or plain text                                  | | ||||
| | `0x54` | Plain Text    | DIF or plain text                                   | | ||||
| | `0xEF` | UTF8 Encoded  | SpreadsheetML / Flat ODS / UOS1 / HTML / plain text | | ||||
| | `0xFF` | UTF16 Encoded | SpreadsheetML / Flat ODS / UOS1 / HTML / plain text | | ||||
| | `0x00` | Record Stream | Lotus WK\* or Quattro Pro or plain text             | | ||||
| | `0x7B` | Plain text    | RTF or plain text                                   | | ||||
| | `0x0A` | Plain text    | SpreadsheetML / Flat ODS / UOS1 / HTML / plain text | | ||||
| | `0x0D` | Plain text    | SpreadsheetML / Flat ODS / UOS1 / HTML / plain text | | ||||
| | `0x20` | Plain text    | SpreadsheetML / Flat ODS / UOS1 / HTML / plain text | | ||||
| 
 | ||||
| DBF files are detected based on the first byte as well as the third and fourth | ||||
| bytes (corresponding to month and day of the file date) | ||||
| 
 | ||||
| Works for Windows files are detected based on the BOF record with type `0xFF` | ||||
| 
 | ||||
| Plain text format guessing follows the priority order: | ||||
| 
 | ||||
| | Format | Test                                                                | | ||||
| |:-------|:--------------------------------------------------------------------| | ||||
| | XML    | `<?xml` appears in the first 1024 characters                        | | ||||
| | HTML   | starts with `<` and HTML tags appear in the first 1024 characters * | | ||||
| | XML    | starts with `<` and the first tag is valid                          | | ||||
| | RTF    | starts with `{\rt`                                                  | | ||||
| | DSV    | starts with `/sep=.$/`, separator is the specified character        | | ||||
| | DSV    | more unquoted `|` chars than `;` `\t`  `,` in the first 1024        | | ||||
| | DSV    | more unquoted `;` chars than `\t` or `,` in the first 1024          | | ||||
| | TSV    | more unquoted `\t` chars than `,` chars in the first 1024           | | ||||
| | CSV    | one of the first 1024 characters is a comma `","`                   | | ||||
| | ETH    | starts with `socialcalc:version:`                                   | | ||||
| | PRN    | `PRN` option is set to true                                         | | ||||
| | CSV    | (fallback)                                                          | | ||||
| 
 | ||||
| - HTML tags include: `html`, `table`, `head`, `meta`, `script`, `style`, `div` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Why are random text files valid?</b> (click to show)</summary> | ||||
| 
 | ||||
| Excel is extremely aggressive in reading files.  Adding an XLS extension to any | ||||
| display text file  (where the only characters are ANSI display chars) tricks | ||||
| Excel into thinking that the file is potentially a CSV or TSV file, even if it | ||||
| is only one column!  This library attempts to replicate that behavior. | ||||
| 
 | ||||
| The best approach is to validate the desired worksheet and ensure it has the | ||||
| expected number of rows or columns.  Extracting the range is extremely simple: | ||||
| 
 | ||||
| ```js | ||||
| var range = XLSX.utils.decode_range(worksheet['!ref']); | ||||
| var ncols = range.e.c - range.s.c + 1, nrows = range.e.r - range.s.r + 1; | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
							
								
								
									
										102
									
								
								docz/docs/08-api/07-write-options.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,102 @@ | ||||
| --- | ||||
| sidebar_position: 7 | ||||
| hide_table_of_contents: true | ||||
| title: Writing Files | ||||
| --- | ||||
| 
 | ||||
| # Writing Options | ||||
| 
 | ||||
| `XLSX.write(wb, write_opts)` attempts to write the workbook `wb` | ||||
| 
 | ||||
| `XLSX.writeFile(wb, filename, write_opts)` attempts to write `wb` to `filename`. | ||||
| In browser-based environments, it will attempt to force a client-side download. | ||||
| 
 | ||||
| `XLSX.writeFileAsync(filename, wb, o, cb)` attempts to write `wb` to `filename`. | ||||
| If `o` is omitted, the writer will use the third argument as the callback. | ||||
| 
 | ||||
| The write functions accept an options argument: | ||||
| 
 | ||||
| | Option Name |  Default | Description                                         | | ||||
| | :---------- | -------: | :-------------------------------------------------- | | ||||
| |`type`       |          | Output data encoding (see Output Type below)        | | ||||
| |`cellDates`  |  `false` | Store dates as type `d` (default is `n`)            | | ||||
| |`bookSST`    |  `false` | Generate Shared String Table **                     | | ||||
| |`bookType`   | `"xlsx"` | Type of Workbook (see below for supported formats)  | | ||||
| |`sheet`      |     `""` | Name of Worksheet for single-sheet formats **       | | ||||
| |`compression`|  `false` | Use ZIP compression for ZIP-based formats **        | | ||||
| |`Props`      |          | Override workbook properties when writing **        | | ||||
| |`themeXLSX`  |          | Override theme XML when writing XLSX/XLSB/XLSM **   | | ||||
| |`ignoreEC`   |   `true` | Suppress "number as text" errors **                 | | ||||
| |`numbers`    |          | Payload for NUMBERS export **                       | | ||||
| 
 | ||||
| - `bookSST` is slower and more memory intensive, but has better compatibility | ||||
|   with older versions of iOS Numbers | ||||
| - The raw data is the only thing guaranteed to be saved.  Features not described | ||||
|   in this README may not be serialized. | ||||
| - `cellDates` only applies to XLSX output and is not guaranteed to work with | ||||
|   third-party readers.  Excel itself does not usually write cells with type `d` | ||||
|   so non-Excel tools may ignore the data or error in the presence of dates. | ||||
| - `Props` is an object mirroring the workbook `Props` field.  See the table from | ||||
|   the [Workbook File Properties](../csf/book#file-properties) section. | ||||
| - if specified, the string from `themeXLSX` will be saved as the primary theme | ||||
|   for XLSX/XLSB/XLSM files (to `xl/theme/theme1.xml` in the ZIP) | ||||
| - Due to a bug in the program, some features like "Text to Columns" will crash | ||||
|   Excel on worksheets where error conditions are ignored.  The writer will mark | ||||
|   files to ignore the error by default.  Set `ignoreEC` to `false` to suppress. | ||||
| - Due to the size of the data, the NUMBERS data is not included by default. The | ||||
|   included `xlsx.zahl.js` and `xlsx.zahl.mjs` scripts include the data. | ||||
| 
 | ||||
| ## Supported Output Formats | ||||
| 
 | ||||
| For broad compatibility with third-party tools, this library supports many | ||||
| output formats.  The specific file type is controlled with `bookType` option: | ||||
| 
 | ||||
| | `bookType` | file ext | container | sheets | Description                     | | ||||
| | :--------- | -------: | :-------: | :----- |:------------------------------- | | ||||
| | `xlsx`     | `.xlsx`  |    ZIP    | multi  | Excel 2007+ XML Format          | | ||||
| | `xlsm`     | `.xlsm`  |    ZIP    | multi  | Excel 2007+ Macro XML Format    | | ||||
| | `xlsb`     | `.xlsb`  |    ZIP    | multi  | Excel 2007+ Binary Format       | | ||||
| | `biff8`    | `.xls`   |    CFB    | multi  | Excel 97-2004 Workbook Format   | | ||||
| | `biff5`    | `.xls`   |    CFB    | multi  | Excel 5.0/95 Workbook Format    | | ||||
| | `biff4`    | `.xls`   |   none    | single | Excel 4.0 Worksheet Format      | | ||||
| | `biff3`    | `.xls`   |   none    | single | Excel 3.0 Worksheet Format      | | ||||
| | `biff2`    | `.xls`   |   none    | single | Excel 2.0 Worksheet Format      | | ||||
| | `xlml`     | `.xls`   |   none    | multi  | Excel 2003-2004 (SpreadsheetML) | | ||||
| | `numbers`  |`.numbers`|    ZIP    | single | Numbers 3.0+ Spreadsheet        | | ||||
| | `ods`      | `.ods`   |    ZIP    | multi  | OpenDocument Spreadsheet        | | ||||
| | `fods`     | `.fods`  |   none    | multi  | Flat OpenDocument Spreadsheet   | | ||||
| | `wk3`      | `.wk3`   |   none    | multi  | Lotus Workbook (WK3)            | | ||||
| | `csv`      | `.csv`   |   none    | single | Comma Separated Values          | | ||||
| | `txt`      | `.txt`   |   none    | single | UTF-16 Unicode Text (TXT)       | | ||||
| | `sylk`     | `.sylk`  |   none    | single | Symbolic Link (SYLK)            | | ||||
| | `html`     | `.html`  |   none    | single | HTML Document                   | | ||||
| | `dif`      | `.dif`   |   none    | single | Data Interchange Format (DIF)   | | ||||
| | `dbf`      | `.dbf`   |   none    | single | dBASE II + VFP Extensions (DBF) | | ||||
| | `wk1`      | `.wk1`   |   none    | single | Lotus Worksheet (WK1)           | | ||||
| | `rtf`      | `.rtf`   |   none    | single | Rich Text Format (RTF)          | | ||||
| | `prn`      | `.prn`   |   none    | single | Lotus Formatted Text            | | ||||
| | `eth`      | `.eth`   |   none    | single | Ethercalc Record Format (ETH)   | | ||||
| 
 | ||||
| - `compression` only applies to formats with ZIP containers. | ||||
| - Formats that only support a single sheet require a `sheet` option specifying | ||||
|   the worksheet.  If the string is empty, the first worksheet is used. | ||||
| - `writeFile` will automatically guess the output file format based on the file | ||||
|   extension if `bookType` is not specified.  It will choose the first format in | ||||
|   the aforementioned table that matches the extension. | ||||
| 
 | ||||
| ## Output Type | ||||
| 
 | ||||
| The `type` argument for `write` mirrors the `type` argument for `read`: | ||||
| 
 | ||||
| | `type`     | output                                                          | | ||||
| |------------|-----------------------------------------------------------------| | ||||
| | `"base64"` | string: Base64 encoding of the file                             | | ||||
| | `"binary"` | string: binary string (byte `n` is `data.charCodeAt(n)`)        | | ||||
| | `"string"` | string: JS string (characters interpreted as UTF8)              | | ||||
| | `"buffer"` | nodejs Buffer                                                   | | ||||
| | `"array"`  | ArrayBuffer, fallback array of 8-bit unsigned int               | | ||||
| | `"file"`   | string: path of file that will be created (nodejs only)         | | ||||
| 
 | ||||
| - For compatibility with Excel, `csv` output will always include the UTF-8 byte | ||||
|   order mark. | ||||
| 
 | ||||
							
								
								
									
										497
									
								
								docz/docs/08-api/09-utilities.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,497 @@ | ||||
| --- | ||||
| sidebar_position: 9 | ||||
| --- | ||||
| 
 | ||||
| 
 | ||||
| # Utility Functions | ||||
| 
 | ||||
| The `sheet_to_*` functions accept a worksheet and an optional options object. | ||||
| 
 | ||||
| The `*_to_sheet` functions accept a data object and an optional options object. | ||||
| 
 | ||||
| The examples are based on the following worksheet: | ||||
| 
 | ||||
| ``` | ||||
| XXX| A | B | C | D | E | F | G | | ||||
| ---+---+---+---+---+---+---+---+ | ||||
|  1 | S | h | e | e | t | J | S | | ||||
|  2 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | ||||
|  3 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | | ||||
| ``` | ||||
| 
 | ||||
| ### Array of Arrays Input | ||||
| 
 | ||||
| `XLSX.utils.aoa_to_sheet` takes an array of arrays of JS values and returns a | ||||
| worksheet resembling the input data.  Numbers, Booleans and Strings are stored | ||||
| as the corresponding styles.  Dates are stored as date or numbers.  Array holes | ||||
| and explicit `undefined` values are skipped.  `null` values may be stubbed. All | ||||
| other values are stored as strings.  The function takes an options argument: | ||||
| 
 | ||||
| | Option Name | Default | Description                                          | | ||||
| | :---------- | :-----: | :--------------------------------------------------- | | ||||
| |`dateNF`     |  FMT 14 | Use specified date format in string output           | | ||||
| |`cellDates`  |  false  | Store dates as type `d` (default is `n`)             | | ||||
| |`sheetStubs` |  false  | Create cell objects of type `z` for `null` values    | | ||||
| |`nullError`  |  false  | If true, emit `#NULL!` error cells for `null` values | | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
| 
 | ||||
| To generate the example sheet: | ||||
| 
 | ||||
| ```js | ||||
| var ws = XLSX.utils.aoa_to_sheet([ | ||||
|   "SheetJS".split(""), | ||||
|   [1,2,3,4,5,6,7], | ||||
|   [2,3,4,5,6,7,8] | ||||
| ]); | ||||
| ``` | ||||
| </details> | ||||
| 
 | ||||
| `XLSX.utils.sheet_add_aoa` takes an array of arrays of JS values and updates an | ||||
| existing worksheet object.  It follows the same process as `aoa_to_sheet` and | ||||
| accepts an options argument: | ||||
| 
 | ||||
| | Option Name | Default | Description                                          | | ||||
| | :---------- | :-----: | :--------------------------------------------------- | | ||||
| |`dateNF`     |  FMT 14 | Use specified date format in string output           | | ||||
| |`cellDates`  |  false  | Store dates as type `d` (default is `n`)             | | ||||
| |`sheetStubs` |  false  | Create cell objects of type `z` for `null` values    | | ||||
| |`nullError`  |  false  | If true, emit `#NULL!` error cells for `null` values | | ||||
| |`origin`     |         | Use specified cell as starting point (see below)     | | ||||
| 
 | ||||
| `origin` is expected to be one of: | ||||
| 
 | ||||
| | `origin`         | Description                                               | | ||||
| | :--------------- | :-------------------------------------------------------- | | ||||
| | (cell object)    | Use specified cell (cell object)                          | | ||||
| | (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                                        | | ||||
| 
 | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
| 
 | ||||
| Consider the worksheet: | ||||
| 
 | ||||
| ``` | ||||
| XXX| A | B | C | D | E | F | G | | ||||
| ---+---+---+---+---+---+---+---+ | ||||
|  1 | S | h | e | e | t | J | S | | ||||
|  2 | 1 | 2 |   |   | 5 | 6 | 7 | | ||||
|  3 | 2 | 3 |   |   | 6 | 7 | 8 | | ||||
|  4 | 3 | 4 |   |   | 7 | 8 | 9 | | ||||
|  5 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | | ||||
| ``` | ||||
| 
 | ||||
| This worksheet can be built up in the order `A1:G1, A2:B4, E2:G4, A5:G5`: | ||||
| 
 | ||||
| ```js | ||||
| /* Initial row */ | ||||
| var ws = XLSX.utils.aoa_to_sheet([ "SheetJS".split("") ]); | ||||
| 
 | ||||
| /* Write data starting at A2 */ | ||||
| XLSX.utils.sheet_add_aoa(ws, [[1,2], [2,3], [3,4]], {origin: "A2"}); | ||||
| 
 | ||||
| /* Write data starting at E2 */ | ||||
| XLSX.utils.sheet_add_aoa(ws, [[5,6,7], [6,7,8], [7,8,9]], {origin:{r:1, c:4}}); | ||||
| 
 | ||||
| /* Append row */ | ||||
| XLSX.utils.sheet_add_aoa(ws, [[4,5,6,7,8,9,0]], {origin: -1}); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ### Array of Objects Input | ||||
| 
 | ||||
| `XLSX.utils.json_to_sheet` takes an array of objects and returns a worksheet | ||||
| with automatically-generated "headers" based on the keys of the objects.  The | ||||
| default column order is determined by the first appearance of the field using | ||||
| `Object.keys`.  The function accepts an options argument: | ||||
| 
 | ||||
| | Option Name | Default | Description                                          | | ||||
| | :---------- | :-----: | :--------------------------------------------------- | | ||||
| |`header`     |         | Use specified field order (default `Object.keys`) ** | | ||||
| |`dateNF`     |  FMT 14 | Use specified date format in string output           | | ||||
| |`cellDates`  |  false  | Store dates as type `d` (default is `n`)             | | ||||
| |`skipHeader` |  false  | If true, do not include header row in output         | | ||||
| |`nullError`  |  false  | If true, emit `#NULL!` error cells for `null` values | | ||||
| 
 | ||||
| - All fields from each row will be written.  If `header` is an array and it does | ||||
|   not contain a particular field, the key will be appended to the array. | ||||
| - Cell types are deduced from the type of each value.  For example, a `Date` | ||||
|   object will generate a Date cell, while a string will generate a Text cell. | ||||
| - Null values will be skipped by default.  If `nullError` is true, an error cell | ||||
|   corresponding to `#NULL!` will be written to the worksheet. | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
| 
 | ||||
| The original sheet cannot be reproduced using plain objects since JS object keys | ||||
| must be unique. After replacing the second `e` and `S` with `e_1` and `S_1`: | ||||
| 
 | ||||
| ```js | ||||
| var ws = XLSX.utils.json_to_sheet([ | ||||
|   { S:1, h:2, e:3, e_1:4, t:5, J:6, S_1:7 }, | ||||
|   { S:2, h:3, e:4, e_1:5, t:6, J:7, S_1:8 } | ||||
| ], {header:["S","h","e","e_1","t","J","S_1"]}); | ||||
| ``` | ||||
| 
 | ||||
| Alternatively, the header row can be skipped: | ||||
| 
 | ||||
| ```js | ||||
| var ws = XLSX.utils.json_to_sheet([ | ||||
|   { A:"S", B:"h", C:"e", D:"e", E:"t", F:"J", G:"S" }, | ||||
|   { A: 1,  B: 2,  C: 3,  D: 4,  E: 5,  F: 6,  G: 7  }, | ||||
|   { A: 2,  B: 3,  C: 4,  D: 5,  E: 6,  F: 7,  G: 8  } | ||||
| ], {header:["A","B","C","D","E","F","G"], skipHeader:true}); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| `XLSX.utils.sheet_add_json` takes an array of objects and updates an existing | ||||
| worksheet object.  It follows the same process as `json_to_sheet` and accepts | ||||
| an options argument: | ||||
| 
 | ||||
| | Option Name | Default | Description                                          | | ||||
| | :---------- | :-----: | :--------------------------------------------------- | | ||||
| |`header`     |         | Use specified column order (default `Object.keys`)   | | ||||
| |`dateNF`     |  FMT 14 | Use specified date format in string output           | | ||||
| |`cellDates`  |  false  | Store dates as type `d` (default is `n`)             | | ||||
| |`skipHeader` |  false  | If true, do not include header row in output         | | ||||
| |`nullError`  |  false  | If true, emit `#NULL!` error cells for `null` values | | ||||
| |`origin`     |         | Use specified cell as starting point (see below)     | | ||||
| 
 | ||||
| `origin` is expected to be one of: | ||||
| 
 | ||||
| | `origin`         | Description                                               | | ||||
| | :--------------- | :-------------------------------------------------------- | | ||||
| | (cell object)    | Use specified cell (cell object)                          | | ||||
| | (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                                        | | ||||
| 
 | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
| 
 | ||||
| Consider the worksheet: | ||||
| 
 | ||||
| ``` | ||||
| XXX| A | B | C | D | E | F | G | | ||||
| ---+---+---+---+---+---+---+---+ | ||||
|  1 | S | h | e | e | t | J | S | | ||||
|  2 | 1 | 2 |   |   | 5 | 6 | 7 | | ||||
|  3 | 2 | 3 |   |   | 6 | 7 | 8 | | ||||
|  4 | 3 | 4 |   |   | 7 | 8 | 9 | | ||||
|  5 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | | ||||
| ``` | ||||
| 
 | ||||
| This worksheet can be built up in the order `A1:G1, A2:B4, E2:G4, A5:G5`: | ||||
| 
 | ||||
| ```js | ||||
| /* Initial row */ | ||||
| var ws = XLSX.utils.json_to_sheet([ | ||||
|   { A: "S", B: "h", C: "e", D: "e", E: "t", F: "J", G: "S" } | ||||
| ], {header: ["A", "B", "C", "D", "E", "F", "G"], skipHeader: true}); | ||||
| 
 | ||||
| /* Write data starting at A2 */ | ||||
| XLSX.utils.sheet_add_json(ws, [ | ||||
|   { A: 1, B: 2 }, { A: 2, B: 3 }, { A: 3, B: 4 } | ||||
| ], {skipHeader: true, origin: "A2"}); | ||||
| 
 | ||||
| /* Write data starting at E2 */ | ||||
| XLSX.utils.sheet_add_json(ws, [ | ||||
|   { A: 5, B: 6, C: 7 }, { A: 6, B: 7, C: 8 }, { A: 7, B: 8, C: 9 } | ||||
| ], {skipHeader: true, origin: { r: 1, c: 4 }, header: [ "A", "B", "C" ]}); | ||||
| 
 | ||||
| /* Append row */ | ||||
| XLSX.utils.sheet_add_json(ws, [ | ||||
|   { A: 4, B: 5, C: 6, D: 7, E: 8, F: 9, G: 0 } | ||||
| ], {header: ["A", "B", "C", "D", "E", "F", "G"], skipHeader: true, origin: -1}); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ### HTML Table Input | ||||
| 
 | ||||
| `XLSX.utils.table_to_sheet` takes a table DOM element and returns a worksheet | ||||
| resembling the input table.  Numbers are parsed.  All other data will be stored | ||||
| as strings. | ||||
| 
 | ||||
| `XLSX.utils.table_to_book` produces a minimal workbook based on the worksheet. | ||||
| 
 | ||||
| Both functions accept options arguments: | ||||
| 
 | ||||
| | Option Name |  Default | Description                                         | | ||||
| | :---------- | :------: | :-------------------------------------------------- | | ||||
| |`raw`        |          | If true, every cell will hold raw strings           | | ||||
| |`dateNF`     |  FMT 14  | Use specified date format in string output          | | ||||
| |`cellDates`  |  false   | Store dates as type `d` (default is `n`)            | | ||||
| |`sheetRows`  |    0     | If >0, read the first `sheetRows` rows of the table | | ||||
| |`display`    |  false   | If true, hidden rows and cells will not be parsed   | | ||||
| 
 | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
| 
 | ||||
| To generate the example sheet, start with the HTML table: | ||||
| 
 | ||||
| ```html | ||||
| <table id="sheetjs"> | ||||
| <tr><td>S</td><td>h</td><td>e</td><td>e</td><td>t</td><td>J</td><td>S</td></tr> | ||||
| <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td></tr> | ||||
| <tr><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td></tr> | ||||
| </table> | ||||
| ``` | ||||
| 
 | ||||
| To process the table: | ||||
| 
 | ||||
| ```js | ||||
| var tbl = document.getElementById('sheetjs'); | ||||
| var wb = XLSX.utils.table_to_book(tbl); | ||||
| ``` | ||||
| </details> | ||||
| 
 | ||||
| Note: `XLSX.read` can handle HTML represented as strings. | ||||
| 
 | ||||
| 
 | ||||
| `XLSX.utils.sheet_add_dom` takes a table DOM element and updates an existing | ||||
| worksheet object.  It follows the same process as `table_to_sheet` and accepts | ||||
| an options argument: | ||||
| 
 | ||||
| | Option Name |  Default | Description                                         | | ||||
| | :---------- | :------: | :-------------------------------------------------- | | ||||
| |`raw`        |          | If true, every cell will hold raw strings           | | ||||
| |`dateNF`     |  FMT 14  | Use specified date format in string output          | | ||||
| |`cellDates`  |  false   | Store dates as type `d` (default is `n`)            | | ||||
| |`sheetRows`  |    0     | If >0, read the first `sheetRows` rows of the table | | ||||
| |`display`    |  false   | If true, hidden rows and cells will not be parsed   | | ||||
| 
 | ||||
| `origin` is expected to be one of: | ||||
| 
 | ||||
| | `origin`         | Description                                               | | ||||
| | :--------------- | :-------------------------------------------------------- | | ||||
| | (cell object)    | Use specified cell (cell object)                          | | ||||
| | (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                                        | | ||||
| 
 | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
| 
 | ||||
| A small helper function can create gap rows between tables: | ||||
| 
 | ||||
| ```js | ||||
| function create_gap_rows(ws, nrows) { | ||||
|   var ref = XLSX.utils.decode_range(ws["!ref"]);       // get original range | ||||
|   ref.e.r += nrows;                                    // add to ending row | ||||
|   ws["!ref"] = XLSX.utils.encode_range(ref);           // reassign row | ||||
| } | ||||
| 
 | ||||
| /* first table */ | ||||
| var ws = XLSX.utils.table_to_sheet(document.getElementById('table1')); | ||||
| create_gap_rows(ws, 1); // one row gap after first table | ||||
| 
 | ||||
| /* second table */ | ||||
| XLSX.utils.sheet_add_dom(ws, document.getElementById('table2'), {origin: -1}); | ||||
| create_gap_rows(ws, 3); // three rows gap after second table | ||||
| 
 | ||||
| /* third table */ | ||||
| XLSX.utils.sheet_add_dom(ws, document.getElementById('table3'), {origin: -1}); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ### Formulae Output | ||||
| 
 | ||||
| `XLSX.utils.sheet_to_formulae` generates an array of commands that represent | ||||
| how a person would enter data into an application.  Each entry is of the form | ||||
| `A1-cell-address=formula-or-value`.  String literals are prefixed with a `'` in | ||||
| accordance with Excel. | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
| 
 | ||||
| For the example sheet: | ||||
| 
 | ||||
| ```js | ||||
| > var o = XLSX.utils.sheet_to_formulae(ws); | ||||
| > [o[0], o[5], o[10], o[15], o[20]]; | ||||
| [ 'A1=\'S', 'F1=\'J', 'D2=4', 'B3=3', 'G3=8' ] | ||||
| ``` | ||||
| </details> | ||||
| 
 | ||||
| ### Delimiter-Separated Output | ||||
| 
 | ||||
| As an alternative to the `writeFile` CSV type, `XLSX.utils.sheet_to_csv` also | ||||
| produces CSV output.  The function takes an options argument: | ||||
| 
 | ||||
| | Option Name  |  Default | Description                                        | | ||||
| | :----------- | :------: | :------------------------------------------------- | | ||||
| |`FS`          |  `","`   | "Field Separator"  delimiter between fields        | | ||||
| |`RS`          |  `"\n"`  | "Record Separator" delimiter between rows          | | ||||
| |`dateNF`      |  FMT 14  | Use specified date format in string output         | | ||||
| |`strip`       |  false   | Remove trailing field separators in each record ** | | ||||
| |`blankrows`   |  true    | Include blank lines in the CSV output              | | ||||
| |`skipHidden`  |  false   | Skips hidden rows/columns in the CSV output        | | ||||
| |`forceQuotes` |  false   | Force quotes around fields                         | | ||||
| 
 | ||||
| - `strip` will remove trailing commas from each line under default `FS/RS` | ||||
| - `blankrows` must be set to `false` to skip blank lines. | ||||
| - Fields containing the record or field separator will automatically be wrapped | ||||
|   in double quotes; `forceQuotes` forces all cells to be wrapped in quotes. | ||||
| - `XLSX.write` with `csv` type will always prepend the UTF-8 byte-order mark for | ||||
|   Excel compatibility.  `sheet_to_csv` returns a JS string and omits the mark. | ||||
|   Using `XLSX.write` with type `string` will also skip the mark. | ||||
| 
 | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
| 
 | ||||
| For the example sheet: | ||||
| 
 | ||||
| ```js | ||||
| > console.log(XLSX.utils.sheet_to_csv(ws)); | ||||
| S,h,e,e,t,J,S | ||||
| 1,2,3,4,5,6,7 | ||||
| 2,3,4,5,6,7,8 | ||||
| > console.log(XLSX.utils.sheet_to_csv(ws, {FS:"\t"})); | ||||
| S	h	e	e	t	J	S | ||||
| 1	2	3	4	5	6	7 | ||||
| 2	3	4	5	6	7	8 | ||||
| > console.log(XLSX.utils.sheet_to_csv(ws,{FS:":",RS:"|"})); | ||||
| S:h:e:e:t:J:S|1:2:3:4:5:6:7|2:3:4:5:6:7:8| | ||||
| ``` | ||||
| </details> | ||||
| 
 | ||||
| #### UTF-16 Unicode Text | ||||
| 
 | ||||
| The `txt` output type uses the tab character as the field separator.  If the | ||||
| `codepage` library is available (included in full distribution but not core), | ||||
| the output will be encoded in `CP1200` and the BOM will be prepended. | ||||
| 
 | ||||
| `XLSX.utils.sheet_to_txt` takes the same arguments as `sheet_to_csv`. | ||||
| 
 | ||||
| ### HTML Output | ||||
| 
 | ||||
| As an alternative to the `writeFile` HTML type, `XLSX.utils.sheet_to_html` also | ||||
| produces HTML output.  The function takes an options argument: | ||||
| 
 | ||||
| | Option Name |  Default | Description                                         | | ||||
| | :---------- | :------: | :-------------------------------------------------- | | ||||
| |`id`         |          | Specify the `id` attribute for the `TABLE` element  | | ||||
| |`editable`   |  false   | If true, set `contenteditable="true"` for every TD  | | ||||
| |`header`     |          | Override header (default `html body`)               | | ||||
| |`footer`     |          | Override footer (default `/body /html`)             | | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
| 
 | ||||
| For the example sheet: | ||||
| 
 | ||||
| ```js | ||||
| > console.log(XLSX.utils.sheet_to_html(ws)); | ||||
| // ... | ||||
| ``` | ||||
| </details> | ||||
| 
 | ||||
| ### JSON | ||||
| 
 | ||||
| `XLSX.utils.sheet_to_json` generates different types of JS objects. The function | ||||
| takes an options argument: | ||||
| 
 | ||||
| | Option Name |  Default | Description                                         | | ||||
| | :---------- | :------: | :-------------------------------------------------- | | ||||
| |`raw`        | `true`   | Use raw values (true) or formatted strings (false)  | | ||||
| |`range`      | from WS  | Override Range (see table below)                    | | ||||
| |`header`     |          | Control output format (see table below)             | | ||||
| |`dateNF`     |  FMT 14  | Use specified date format in string output          | | ||||
| |`defval`     |          | Use specified value in place of null or undefined   | | ||||
| |`blankrows`  |    **    | Include blank lines in the output **                | | ||||
| 
 | ||||
| - `raw` only affects cells which have a format code (`.z`) field or a formatted | ||||
|   text (`.w`) field. | ||||
| - If `header` is specified, the first row is considered a data row; if `header` | ||||
|   is not specified, the first row is the header row and not considered data. | ||||
| - When `header` is not specified, the conversion will automatically disambiguate | ||||
|   header entries by affixing `_` and a count starting at `1`.  For example, if | ||||
|   three columns have header `foo` the output fields are `foo`, `foo_1`, `foo_2` | ||||
| - `null` values are returned when `raw` is true but are skipped when false. | ||||
| - If `defval` is not specified, null and undefined values are skipped normally. | ||||
|   If specified, all null and undefined points will be filled with `defval` | ||||
| - When `header` is `1`, the default is to generate blank rows.  `blankrows` must | ||||
|   be set to `false` to skip blank rows. | ||||
| - When `header` is not `1`, the default is to skip blank rows.  `blankrows` must | ||||
|   be true to generate blank rows | ||||
| 
 | ||||
| `range` is expected to be one of: | ||||
| 
 | ||||
| | `range`          | Description                                               | | ||||
| | :--------------- | :-------------------------------------------------------- | | ||||
| | (number)         | Use worksheet range but set starting row to the value     | | ||||
| | (string)         | Use specified range (A1-style bounded range string)       | | ||||
| | (default)        | Use worksheet range (`ws['!ref']`)                        | | ||||
| 
 | ||||
| `header` is expected to be one of: | ||||
| 
 | ||||
| | `header`         | Description                                               | | ||||
| | :--------------- | :-------------------------------------------------------- | | ||||
| | `1`              | Generate an array of arrays ("2D Array")                  | | ||||
| | `"A"`            | Row object keys are literal column labels                 | | ||||
| | array of strings | Use specified strings as keys in row objects              | | ||||
| | (default)        | Read and disambiguate first row as keys                   | | ||||
| 
 | ||||
| - If header is not `1`, the row object will contain the non-enumerable property | ||||
|   `__rowNum__` that represents the row of the sheet corresponding to the entry. | ||||
| - If header is an array, the keys will not be disambiguated.  This can lead to | ||||
|   unexpected results if the array values are not unique! | ||||
| 
 | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
| 
 | ||||
| For the example sheet: | ||||
| 
 | ||||
| ```js | ||||
| > XLSX.utils.sheet_to_json(ws); | ||||
| [ { S: 1, h: 2, e: 3, e_1: 4, t: 5, J: 6, S_1: 7 }, | ||||
|   { S: 2, h: 3, e: 4, e_1: 5, t: 6, J: 7, S_1: 8 } ] | ||||
| 
 | ||||
| > XLSX.utils.sheet_to_json(ws, {header:"A"}); | ||||
| [ { A: 'S', B: 'h', C: 'e', D: 'e', E: 't', F: 'J', G: 'S' }, | ||||
|   { A: '1', B: '2', C: '3', D: '4', E: '5', F: '6', G: '7' }, | ||||
|   { A: '2', B: '3', C: '4', D: '5', E: '6', F: '7', G: '8' } ] | ||||
| 
 | ||||
| > XLSX.utils.sheet_to_json(ws, {header:["A","E","I","O","U","6","9"]}); | ||||
| [ { '6': 'J', '9': 'S', A: 'S', E: 'h', I: 'e', O: 'e', U: 't' }, | ||||
|   { '6': '6', '9': '7', A: '1', E: '2', I: '3', O: '4', U: '5' }, | ||||
|   { '6': '7', '9': '8', A: '2', E: '3', I: '4', O: '5', U: '6' } ] | ||||
| 
 | ||||
| > XLSX.utils.sheet_to_json(ws, {header:1}); | ||||
| [ [ 'S', 'h', 'e', 'e', 't', 'J', 'S' ], | ||||
|   [ '1', '2', '3', '4', '5', '6', '7' ], | ||||
|   [ '2', '3', '4', '5', '6', '7', '8' ] ] | ||||
| ``` | ||||
| 
 | ||||
| Example showing the effect of `raw`: | ||||
| 
 | ||||
| ```js | ||||
| > ws['A2'].w = "3";                          // set A2 formatted string value | ||||
| 
 | ||||
| > XLSX.utils.sheet_to_json(ws, {header:1, raw:false}); | ||||
| [ [ 'S', 'h', 'e', 'e', 't', 'J', 'S' ], | ||||
|   [ '3', '2', '3', '4', '5', '6', '7' ],     // <-- A2 uses the formatted string | ||||
|   [ '2', '3', '4', '5', '6', '7', '8' ] ] | ||||
| 
 | ||||
| > XLSX.utils.sheet_to_json(ws, {header:1}); | ||||
| [ [ 'S', 'h', 'e', 'e', 't', 'J', 'S' ], | ||||
|   [ 1, 2, 3, 4, 5, 6, 7 ],                   // <-- A2 uses the raw value | ||||
|   [ 2, 3, 4, 5, 6, 7, 8 ] ] | ||||
| ``` | ||||
| </details> | ||||
							
								
								
									
										4
									
								
								docz/docs/08-api/_category_.json
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,4 @@ | ||||
| { | ||||
|   "label": "API Functions", | ||||
|   "position": 8 | ||||
| } | ||||
							
								
								
									
										255
									
								
								docz/docs/09-miscellany/01-formats.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,255 @@ | ||||
| --- | ||||
| sidebar_position: 1 | ||||
| --- | ||||
| 
 | ||||
| # File Formats | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| 
 | ||||
| | Format                                                       | Read  | Write | | ||||
| |:-------------------------------------------------------------|:-----:|:-----:| | ||||
| | **Excel Worksheet/Workbook Formats**                         |:-----:|:-----:| | ||||
| | Excel 2007+ XML Formats (XLSX/XLSM)                          |   ✔   |   ✔   | | ||||
| | Excel 2007+ Binary Format (XLSB BIFF12)                      |   ✔   |   ✔   | | ||||
| | Excel 2003-2004 XML Format (XML "SpreadsheetML")             |   ✔   |   ✔   | | ||||
| | Excel 97-2004 (XLS BIFF8)                                    |   ✔   |   ✔   | | ||||
| | Excel 5.0/95 (XLS BIFF5)                                     |   ✔   |   ✔   | | ||||
| | Excel 4.0 (XLS/XLW BIFF4)                                    |   ✔   |   ✔   | | ||||
| | Excel 3.0 (XLS BIFF3)                                        |   ✔   |   ✔   | | ||||
| | Excel 2.0/2.1 / Multiplan 4.x DOS (XLS BIFF2)                |   ✔   |   ✔   | | ||||
| | **Excel Supported Text Formats**                             |:-----:|:-----:| | ||||
| | Delimiter-Separated Values (CSV/TXT)                         |   ✔   |   ✔   | | ||||
| | Data Interchange Format (DIF)                                |   ✔   |   ✔   | | ||||
| | Symbolic Link (SYLK/SLK)                                     |   ✔   |   ✔   | | ||||
| | Lotus Formatted Text (PRN)                                   |   ✔   |   ✔   | | ||||
| | UTF-16 Unicode Text (TXT)                                    |   ✔   |   ✔   | | ||||
| | **Other Workbook/Worksheet Formats**                         |:-----:|:-----:| | ||||
| | Numbers 3.0+ / iWork 2013+ Spreadsheet (NUMBERS)             |   ✔   |   ✔   | | ||||
| | OpenDocument Spreadsheet (ODS)                               |   ✔   |   ✔   | | ||||
| | Flat XML ODF Spreadsheet (FODS)                              |   ✔   |   ✔   | | ||||
| | Uniform Office Format Spreadsheet (标文通 UOS1/UOS2)         |   ✔   |       | | ||||
| | dBASE II/III/IV / Visual FoxPro (DBF)                        |   ✔   |   ✔   | | ||||
| | Lotus 1-2-3 (WK1/WK3)                                        |   ✔   |   ✔   | | ||||
| | Lotus 1-2-3 (WKS/WK2/WK4/123)                                |   ✔   |       | | ||||
| | Quattro Pro Spreadsheet (WQ1/WQ2/WB1/WB2/WB3/QPW)            |   ✔   |       | | ||||
| | Works 1.x-3.x DOS / 2.x-5.x Windows Spreadsheet (WKS)        |   ✔   |       | | ||||
| | Works 6.x-9.x Spreadsheet (XLR)                              |   ✔   |       | | ||||
| | **Other Common Spreadsheet Output Formats**                  |:-----:|:-----:| | ||||
| | HTML Tables                                                  |   ✔   |   ✔   | | ||||
| | Rich Text Format tables (RTF)                                |       |   ✔   | | ||||
| | Ethercalc Record Format (ETH)                                |   ✔   |   ✔   | | ||||
| 
 | ||||
| Features not supported by a given file format will not be written.  Formats with | ||||
| 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.0 (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. | ||||
| 
 | ||||
| ### Excel 2007+ XML (XLSX/XLSM) | ||||
| 
 | ||||
| XLSX and XLSM files are ZIP containers containing a series of XML files in | ||||
| accordance with the Open Packaging Conventions (OPC).  The XLSM format, almost | ||||
| identical to XLSX, is used for files containing macros. | ||||
| 
 | ||||
| The format is standardized in ECMA-376 and later in ISO/IEC 29500.  Excel does | ||||
| not follow the specification, and there are additional documents discussing how | ||||
| Excel deviates from the specification. | ||||
| 
 | ||||
| ### Excel 2.0-95 (BIFF2/BIFF3/BIFF4/BIFF5) | ||||
| 
 | ||||
| BIFF 2/3 XLS are single-sheet streams of binary records.  Excel 4 introduced | ||||
| the concept of a workbook (`XLW` files) but also had single-sheet `XLS` format. | ||||
| The structure is largely similar to the Lotus 1-2-3 file formats.  BIFF5/8/12 | ||||
| extended the format in various ways but largely stuck to the same record format. | ||||
| 
 | ||||
| Multiplan 4 "Normal" files are identical in structure to BIFF2 and use the same | ||||
| cell value records.  There are some different record types for more advanced | ||||
| features like Print Settings.  The BIFF2 writer generates files that can be read | ||||
| in Multiplan 4 and the parser can extract values from "Normal" files. | ||||
| 
 | ||||
| There is no official specification for any of these formats.  Excel 95 can write | ||||
| files in these formats, so record lengths and fields were determined by writing | ||||
| in all of the supported formats and comparing files.  Excel 2016 can generate | ||||
| BIFF5 files, enabling a full suite of file tests starting from XLSX or BIFF2. | ||||
| 
 | ||||
| ### Excel 97-2004 Binary (BIFF8) | ||||
| 
 | ||||
| BIFF8 exclusively uses the Compound File Binary container format, splitting some | ||||
| content into streams within the file.  At its core, it still uses an extended | ||||
| version of the binary record format from older versions of BIFF. | ||||
| 
 | ||||
| The `MS-XLS` specification covers the basics of the file format, and other | ||||
| specifications expand on serialization of features like properties. | ||||
| 
 | ||||
| ### Excel 2003-2004 (SpreadsheetML) | ||||
| 
 | ||||
| Predating XLSX, SpreadsheetML files are simple XML files.  There is no official | ||||
| and comprehensive specification, although MS has released documentation on the | ||||
| format.  Since Excel 2016 can generate SpreadsheetML files, mapping features is | ||||
| pretty straightforward. | ||||
| 
 | ||||
| ### Excel 2007+ Binary (XLSB, BIFF12) | ||||
| 
 | ||||
| Introduced in parallel with XLSX, the XLSB format combines the BIFF architecture | ||||
| with the content separation and ZIP container of XLSX.  For the most part nodes | ||||
| in an XLSX sub-file can be mapped to XLSB records in a corresponding sub-file. | ||||
| 
 | ||||
| The `MS-XLSB` specification covers the basics of the file format, and other | ||||
| specifications expand on serialization of features like properties. | ||||
| 
 | ||||
| ### Delimiter-Separated Values (CSV/TXT) | ||||
| 
 | ||||
| Excel CSV deviates from RFC4180 in a number of important ways.  The generated | ||||
| CSV files should generally work in Excel although they may not work in RFC4180 | ||||
| compatible readers.  The parser should generally understand Excel CSV. The | ||||
| writer proactively generates cells for formulae if values are unavailable. | ||||
| 
 | ||||
| Excel TXT uses tab as the delimiter and code page 1200. | ||||
| 
 | ||||
| Like in Excel, files starting with `0x49 0x44 ("ID")` are treated as Symbolic | ||||
| Link files.  Unlike Excel, if the file does not have a valid SYLK header, it | ||||
| will be proactively reinterpreted as CSV.  There are some files with semicolon | ||||
| delimiter that align with a valid SYLK file.  For the broadest compatibility, | ||||
| all cells with the value of `ID` are automatically wrapped in double-quotes. | ||||
| 
 | ||||
| ### Miscellaneous Workbook Formats | ||||
| 
 | ||||
| Support for other formats is generally far behind XLS/XLSB/XLSX support, due in | ||||
| part to a lack of publicly available documentation.  Test files were produced in | ||||
| the respective apps and compared to their XLS exports to determine structure. | ||||
| The main focus is data extraction. | ||||
| 
 | ||||
| #### Lotus 1-2-3 (WKS/WK1/WK2/WK3/WK4/123) | ||||
| 
 | ||||
| The Lotus formats consist of binary records similar to the BIFF structure. Lotus | ||||
| did release a specification decades ago covering the original WK1 format.  Other | ||||
| features were deduced by producing files and comparing to Excel support. | ||||
| 
 | ||||
| Generated WK1 worksheets are compatible with Lotus 1-2-3 R2 and Excel 5.0. | ||||
| 
 | ||||
| Generated WK3 workbooks are compatible with Lotus 1-2-3 R9 and Excel 5.0. | ||||
| 
 | ||||
| #### Quattro Pro (WQ1/WQ2/WB1/WB2/WB3/QPW) | ||||
| 
 | ||||
| The Quattro Pro formats use binary records in the same way as BIFF and Lotus. | ||||
| Some of the newer formats (namely WB3 and QPW) use a CFB enclosure just like | ||||
| BIFF8 XLS. | ||||
| 
 | ||||
| #### Works for DOS / Windows Spreadsheet (WKS/XLR) | ||||
| 
 | ||||
| All versions of Works were limited to a single worksheet. | ||||
| 
 | ||||
| Works for DOS 1.x - 3.x and Works for Windows 2.x extends the Lotus WKS format | ||||
| with additional record types. | ||||
| 
 | ||||
| Works for Windows 3.x - 5.x uses the same format and WKS extension.  The BOF | ||||
| record has type `FF` | ||||
| 
 | ||||
| Works for Windows 6.x - 9.x use the XLR format.  XLR is nearly identical to | ||||
| BIFF8 XLS: it uses the CFB container with a Workbook stream.  Works 9 saves the | ||||
| exact Workbook stream for the XLR and the 97-2003 XLS export.  Works 6 XLS | ||||
| includes two empty worksheets but the main worksheet has an identical encoding. | ||||
| XLR also includes a `WksSSWorkBook` stream similar to Lotus FM3/FMT files. | ||||
| 
 | ||||
| #### Numbers 3.0+ / iWork 2013+ Spreadsheet (NUMBERS) | ||||
| 
 | ||||
| iWork 2013 (Numbers 3.0 / Pages 5.0 / Keynote 6.0) switched from a proprietary | ||||
| XML-based format to the current file format based on the iWork Archive (IWA). | ||||
| This format has been used up through the current release (Numbers 11.2). | ||||
| 
 | ||||
| The parser focuses on extracting raw data from tables.  Numbers technically | ||||
| supports multiple tables in a logical worksheet, including custom titles.  This | ||||
| parser will generate one worksheet per Numbers table. | ||||
| 
 | ||||
| The writer currently exports a small range from the first worksheet. | ||||
| 
 | ||||
| #### OpenDocument Spreadsheet (ODS/FODS) | ||||
| 
 | ||||
| ODS is an XML-in-ZIP format akin to XLSX while FODS is an XML format akin to | ||||
| SpreadsheetML.  Both are detailed in the OASIS standard, but tools like LO/OO | ||||
| add undocumented extensions.  The parsers and writers do not implement the full | ||||
| standard, instead focusing on parts necessary to extract and store raw data. | ||||
| 
 | ||||
| #### Uniform Office Spreadsheet (UOS1/2) | ||||
| 
 | ||||
| UOS is a very similar format, and it comes in 2 varieties corresponding to ODS | ||||
| and FODS respectively.  For the most part, the difference between the formats | ||||
| is in the names of tags and attributes. | ||||
| 
 | ||||
| ### Miscellaneous Worksheet Formats | ||||
| 
 | ||||
| Many older formats supported only one worksheet: | ||||
| 
 | ||||
| #### dBASE and Visual FoxPro (DBF) | ||||
| 
 | ||||
| DBF is really a typed table format: each column can only hold one data type and | ||||
| each record omits type information.  The parser generates a header row and | ||||
| inserts records starting at the second row of the worksheet.  The writer makes | ||||
| 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. | ||||
| 
 | ||||
| #### Symbolic Link (SYLK) | ||||
| 
 | ||||
| <https://oss.sheetjs.com/notes/sylk/> is an informal specification based on our | ||||
| experimentation and previous documentation efforts. | ||||
| 
 | ||||
| #### Lotus Formatted Text (PRN) | ||||
| 
 | ||||
| There is no real documentation, and in fact Excel treats PRN as an output-only | ||||
| file format.  Nevertheless we can guess the column widths and reverse-engineer | ||||
| the original layout.  Excel's 240 character width limitation is not enforced. | ||||
| 
 | ||||
| #### Data Interchange Format (DIF) | ||||
| 
 | ||||
| There is no unified definition.  Visicalc DIF differs from Lotus DIF, and both | ||||
| differ from Excel DIF.  Where ambiguous, the parser/writer follows the expected | ||||
| behavior from Excel.  In particular, Excel extends DIF in incompatible ways: | ||||
| 
 | ||||
| - Since Excel automatically converts numbers-as-strings to numbers, numeric | ||||
|   string constants are converted to formulae: `"0.3" -> "=""0.3""` | ||||
| - DIF technically expects numeric cells to hold the raw numeric data, but Excel | ||||
|   permits formatted numbers (including dates) | ||||
| - DIF technically has no support for formulae, but Excel will automatically | ||||
|   convert plain formulae.  Array formulae are not preserved. | ||||
| 
 | ||||
| #### HTML | ||||
| 
 | ||||
| Excel HTML worksheets include special metadata encoded in styles.  For example, | ||||
| `mso-number-format` is a localized string containing the number format.  Despite | ||||
| the metadata the output is valid HTML, although it does accept bare `&` symbols. | ||||
| 
 | ||||
| The writer adds type metadata to the TD elements via the `t` tag.  The parser | ||||
| looks for those tags and overrides the default interpretation. For example, text | ||||
| like `<td>12345</td>` will be parsed as numbers but `<td t="s">12345</td>` will | ||||
| be parsed as text. | ||||
| 
 | ||||
| #### Rich Text Format (RTF) | ||||
| 
 | ||||
| Excel RTF worksheets are stored in clipboard when copying cells or ranges from a | ||||
| worksheet.  The supported codes are a subset of the Word RTF support. | ||||
| 
 | ||||
| #### Ethercalc Record Format (ETH) | ||||
| 
 | ||||
| [Ethercalc](https://ethercalc.net/) is an open source web spreadsheet powered by | ||||
| a record format reminiscent of SYLK wrapped in a MIME multi-part message. | ||||
| 
 | ||||
							
								
								
									
										111
									
								
								docz/docs/09-miscellany/06-testing.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,111 @@ | ||||
| --- | ||||
| sidebar_position: 6 | ||||
| hide_table_of_contents: true | ||||
| --- | ||||
| 
 | ||||
| # Testing | ||||
| 
 | ||||
| import Tabs from '@theme/Tabs'; | ||||
| import TabItem from '@theme/TabItem'; | ||||
| 
 | ||||
| <Tabs> | ||||
|   <TabItem value="nodejs" label="NodeJS"> | ||||
| 
 | ||||
| `make test` will run the node-based tests.  By default it runs tests on files in | ||||
| every supported format.  To test a specific file type, set `FMTS` to the format | ||||
| you want to test.  Feature-specific tests are available with `make test_misc` | ||||
| 
 | ||||
| ```bash | ||||
| $ make test_misc   # run core tests | ||||
| $ make test        # run full tests | ||||
| $ make test_xls    # only use the XLS test files | ||||
| $ make test_xlsx   # only use the XLSX test files | ||||
| $ make test_xlsb   # only use the XLSB test files | ||||
| $ make test_xml    # only use the XML test files | ||||
| $ make test_ods    # only use the ODS test files | ||||
| ``` | ||||
| 
 | ||||
| To enable all errors, set the environment variable `WTF=1`: | ||||
| 
 | ||||
| ```bash | ||||
| $ make test        # run full tests | ||||
| $ WTF=1 make test  # enable all error messages | ||||
| ``` | ||||
| 
 | ||||
| `flow` and `eslint` checks are available: | ||||
| 
 | ||||
| ```bash | ||||
| $ make lint        # eslint checks | ||||
| $ make flow        # make lint + Flow checking | ||||
| $ make tslint      # check TS definitions | ||||
| ``` | ||||
| 
 | ||||
|   </TabItem> | ||||
|   <TabItem value="browser" label="Browser"> | ||||
| 
 | ||||
| The core in-browser tests are available at `tests/index.html` within this repo. | ||||
| Start a local server and navigate to that directory to run the tests. | ||||
| `make ctestserv` will start a server on port 8000. | ||||
| 
 | ||||
| `make ctest` will generate the browser fixtures.  To add more files, edit the | ||||
| `tests/fixtures.lst` file and add the paths. | ||||
| 
 | ||||
| To run the full in-browser tests, clone the repo for | ||||
| [`oss.sheetjs.com`](https://github.com/SheetJS/SheetJS.github.io) and replace | ||||
| the `xlsx.js` file (then open a browser window and go to `stress.html`): | ||||
| 
 | ||||
| ```bash | ||||
| $ cp xlsx.js ../SheetJS.github.io | ||||
| $ cd ../SheetJS.github.io | ||||
| $ simplehttpserver # or "python -mSimpleHTTPServer" or "serve" | ||||
| $ open -a Chromium.app http://localhost:8000/stress.html | ||||
| ``` | ||||
| 
 | ||||
|   </TabItem> | ||||
|   <TabItem value="deno" label="Deno"> | ||||
| 
 | ||||
| `make test-deno` will run the full Deno test suite and `make test-deno_misc` | ||||
| will run the smaller feature-specific tests. | ||||
| 
 | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
| 
 | ||||
| ### Tested Environments | ||||
| 
 | ||||
| <details> | ||||
|   <summary>(click to show)</summary> | ||||
| 
 | ||||
|  - NodeJS `0.8`, `0.10`, `0.12`, `4.x`, `5.x`, `6.x`, `7.x`, `8.x` | ||||
|  - IE 6/7/8/9/10/11 (IE 6-9 require shims) | ||||
|  - Chrome 24+ (including Android 4.0+) | ||||
|  - Safari 6+ (iOS and Desktop) | ||||
|  - Edge 13+, FF 18+, and Opera 12+ | ||||
| 
 | ||||
| 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: | ||||
| 
 | ||||
| ```bash | ||||
| $ env TZ="Asia/Kolkata" WTF=1 make test_misc | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ### Test Files | ||||
| 
 | ||||
| Test files are housed in [another repo](https://github.com/SheetJS/test_files). | ||||
| 
 | ||||
| Running `make init` will refresh the `test_files` submodule and get the files. | ||||
| Note that this requires `svn`, `git`, `hg` and other commands that may not be | ||||
| available.  If `make init` fails, please download the latest version of the test | ||||
| files snapshot from [the repo](https://github.com/SheetJS/test_files/releases) | ||||
| 
 | ||||
| #### Latest Snapshot | ||||
| 
 | ||||
| <http://github.com/SheetJS/test_files/releases/download/20170409/test_files.zip> | ||||
| 
 | ||||
| (download and unzip to the `test_files` subdirectory) | ||||
| 
 | ||||
							
								
								
									
										122
									
								
								docz/docs/09-miscellany/07-contributing.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,122 @@ | ||||
| --- | ||||
| sidebar_position: 7 | ||||
| hide_table_of_contents: true | ||||
| --- | ||||
| 
 | ||||
| # Contributing | ||||
| 
 | ||||
| Due to the precarious nature of the Open Specifications Promise, it is very | ||||
| important to ensure code is cleanroom.  [Contribution Notes](https://raw.githubusercontent.com/SheetJS/sheetjs/master/CONTRIBUTING.md) | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>File organization</b> (click to show)</summary> | ||||
| 
 | ||||
| At a high level, the final script is a concatenation of the individual files in | ||||
| the `bits` folder.  Running `make` should reproduce the final output on all | ||||
| platforms. | ||||
| 
 | ||||
| Folders: | ||||
| 
 | ||||
| | folder       | contents                                                      | | ||||
| |:-------------|:--------------------------------------------------------------| | ||||
| | `bits`       | raw source files that make up the final script                | | ||||
| | `bin`        | server-side bin scripts (`xlsx.njs`)                          | | ||||
| | `dist`       | dist files for web browsers and nonstandard JS environments   | | ||||
| | `demos`      | demo projects for platforms like ExtendScript and Webpack     | | ||||
| | `tests`      | browser tests (run `make ctest` to rebuild)                   | | ||||
| | `types`      | typescript definitions and tests                              | | ||||
| | `misc`       | miscellaneous supporting scripts                              | | ||||
| | `test_files` | test files (pulled from the test files repository)            | | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| After cloning the repo, running `make help` will display a list of commands. | ||||
| 
 | ||||
| ## Platform-Specific Details | ||||
| 
 | ||||
| import Tabs from '@theme/Tabs'; | ||||
| import TabItem from '@theme/TabItem'; | ||||
| 
 | ||||
| <Tabs> | ||||
|   <TabItem value="osx" label="OSX/Linux"> | ||||
| 
 | ||||
| The `xlsx.js` file is constructed from the files in the `bits` subdirectory. The | ||||
| build script (run `make`) will concatenate the individual bits to produce the | ||||
| script.  Before submitting a contribution, ensure that running make will produce | ||||
| the `xlsx.js` file exactly.  The simplest way to test is to add the script: | ||||
| 
 | ||||
| ```bash | ||||
| $ git add xlsx.js | ||||
| $ make clean | ||||
| $ make | ||||
| $ git diff xlsx.js | ||||
| ``` | ||||
| 
 | ||||
| To produce the dist files, run `make dist`.  The dist files are updated in each | ||||
| version release and *should not be committed between versions*. | ||||
| 
 | ||||
|   </TabItem> | ||||
|   <TabItem value="win" label="Windows"> | ||||
| 
 | ||||
| The included `make.cmd` script will build `xlsx.js` from the `bits` directory. | ||||
| Building is as simple as: | ||||
| 
 | ||||
| ```cmd | ||||
| > make | ||||
| ``` | ||||
| 
 | ||||
| To prepare development environment: | ||||
| 
 | ||||
| ```cmd | ||||
| > make init | ||||
| ``` | ||||
| 
 | ||||
| The full list of commands available in Windows are displayed in `make help`: | ||||
| 
 | ||||
| ``` | ||||
| make init -- install deps and global modules | ||||
| make lint -- run eslint linter | ||||
| make test -- run mocha test suite | ||||
| make misc -- run smaller test suite | ||||
| make book -- rebuild README and summary | ||||
| make help -- display this message | ||||
| ``` | ||||
| 
 | ||||
| As explained in [Test Files](./testing#test-files), on Windows the release ZIP file must | ||||
| be downloaded and extracted.  If Bash on Windows is available, it is possible | ||||
| to run the OSX/Linux workflow.  The following steps prepares the environment: | ||||
| 
 | ||||
| ```bash | ||||
| # Install support programs for the build and test commands | ||||
| sudo apt-get install make git subversion mercurial | ||||
| 
 | ||||
| # Install nodejs and NPM within the WSL | ||||
| wget -qO- https://deb.nodesource.com/setup_8.x | sudo bash | ||||
| sudo apt-get install nodejs | ||||
| 
 | ||||
| # Install dev dependencies | ||||
| sudo npm install -g mocha voc blanket xlsjs | ||||
| ``` | ||||
| 
 | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
| 
 | ||||
| ### Tests | ||||
| 
 | ||||
| The `test_misc` target (`make test_misc` on Linux/OSX / `make misc` on Windows) | ||||
| runs the targeted feature tests.  It should take 5-10 seconds to perform feature | ||||
| tests without testing against the entire test battery.  New features should be | ||||
| accompanied with tests for the relevant file formats and features. | ||||
| 
 | ||||
| For tests involving the read side, an appropriate feature test would involve | ||||
| reading an existing file and checking the resulting workbook object.  If a | ||||
| parameter is involved, files should be read with different values to verify that | ||||
| the feature is working as expected. | ||||
| 
 | ||||
| For tests involving a new write feature which can already be parsed, appropriate | ||||
| feature tests would involve writing a workbook with the feature and then opening | ||||
| and verifying that the feature is preserved. | ||||
| 
 | ||||
| For tests involving a new write feature without an existing read ability, please | ||||
| add a feature test to the kitchen sink `tests/write.js`. | ||||
| 
 | ||||
							
								
								
									
										218
									
								
								docz/docs/09-miscellany/08-license.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,218 @@ | ||||
| --- | ||||
| sidebar_position: 8 | ||||
| hide_table_of_contents: true | ||||
| --- | ||||
| 
 | ||||
| # License | ||||
| 
 | ||||
| SheetJS Community Edition is licensed under the "Apache 2.0 License". All rights | ||||
| not explicitly granted by the Apache 2.0 License are reserved by SheetJS LLC. | ||||
| 
 | ||||
| <details><summary><b>License</b> (click to show)</summary> | ||||
| 
 | ||||
| ``` | ||||
|                                  Apache License | ||||
|                            Version 2.0, January 2004 | ||||
|                         http://www.apache.org/licenses/ | ||||
| 
 | ||||
|    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||||
| 
 | ||||
|    1. Definitions. | ||||
| 
 | ||||
|       "License" shall mean the terms and conditions for use, reproduction, | ||||
|       and distribution as defined by Sections 1 through 9 of this document. | ||||
| 
 | ||||
|       "Licensor" shall mean the copyright owner or entity authorized by | ||||
|       the copyright owner that is granting the License. | ||||
| 
 | ||||
|       "Legal Entity" shall mean the union of the acting entity and all | ||||
|       other entities that control, are controlled by, or are under common | ||||
|       control with that entity. For the purposes of this definition, | ||||
|       "control" means (i) the power, direct or indirect, to cause the | ||||
|       direction or management of such entity, whether by contract or | ||||
|       otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||||
|       outstanding shares, or (iii) beneficial ownership of such entity. | ||||
| 
 | ||||
|       "You" (or "Your") shall mean an individual or Legal Entity | ||||
|       exercising permissions granted by this License. | ||||
| 
 | ||||
|       "Source" form shall mean the preferred form for making modifications, | ||||
|       including but not limited to software source code, documentation | ||||
|       source, and configuration files. | ||||
| 
 | ||||
|       "Object" form shall mean any form resulting from mechanical | ||||
|       transformation or translation of a Source form, including but | ||||
|       not limited to compiled object code, generated documentation, | ||||
|       and conversions to other media types. | ||||
| 
 | ||||
|       "Work" shall mean the work of authorship, whether in Source or | ||||
|       Object form, made available under the License, as indicated by a | ||||
|       copyright notice that is included in or attached to the work | ||||
|       (an example is provided in the Appendix below). | ||||
| 
 | ||||
|       "Derivative Works" shall mean any work, whether in Source or Object | ||||
|       form, that is based on (or derived from) the Work and for which the | ||||
|       editorial revisions, annotations, elaborations, or other modifications | ||||
|       represent, as a whole, an original work of authorship. For the purposes | ||||
|       of this License, Derivative Works shall not include works that remain | ||||
|       separable from, or merely link (or bind by name) to the interfaces of, | ||||
|       the Work and Derivative Works thereof. | ||||
| 
 | ||||
|       "Contribution" shall mean any work of authorship, including | ||||
|       the original version of the Work and any modifications or additions | ||||
|       to that Work or Derivative Works thereof, that is intentionally | ||||
|       submitted to Licensor for inclusion in the Work by the copyright owner | ||||
|       or by an individual or Legal Entity authorized to submit on behalf of | ||||
|       the copyright owner. For the purposes of this definition, "submitted" | ||||
|       means any form of electronic, verbal, or written communication sent | ||||
|       to the Licensor or its representatives, including but not limited to | ||||
|       communication on electronic mailing lists, source code control systems, | ||||
|       and issue tracking systems that are managed by, or on behalf of, the | ||||
|       Licensor for the purpose of discussing and improving the Work, but | ||||
|       excluding communication that is conspicuously marked or otherwise | ||||
|       designated in writing by the copyright owner as "Not a Contribution." | ||||
| 
 | ||||
|       "Contributor" shall mean Licensor and any individual or Legal Entity | ||||
|       on behalf of whom a Contribution has been received by Licensor and | ||||
|       subsequently incorporated within the Work. | ||||
| 
 | ||||
|    2. Grant of Copyright License. Subject to the terms and conditions of | ||||
|       this License, each Contributor hereby grants to You a perpetual, | ||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||
|       copyright license to reproduce, prepare Derivative Works of, | ||||
|       publicly display, publicly perform, sublicense, and distribute the | ||||
|       Work and such Derivative Works in Source or Object form. | ||||
| 
 | ||||
|    3. Grant of Patent License. Subject to the terms and conditions of | ||||
|       this License, each Contributor hereby grants to You a perpetual, | ||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||
|       (except as stated in this section) patent license to make, have made, | ||||
|       use, offer to sell, sell, import, and otherwise transfer the Work, | ||||
|       where such license applies only to those patent claims licensable | ||||
|       by such Contributor that are necessarily infringed by their | ||||
|       Contribution(s) alone or by combination of their Contribution(s) | ||||
|       with the Work to which such Contribution(s) was submitted. If You | ||||
|       institute patent litigation against any entity (including a | ||||
|       cross-claim or counterclaim in a lawsuit) alleging that the Work | ||||
|       or a Contribution incorporated within the Work constitutes direct | ||||
|       or contributory patent infringement, then any patent licenses | ||||
|       granted to You under this License for that Work shall terminate | ||||
|       as of the date such litigation is filed. | ||||
| 
 | ||||
|    4. Redistribution. You may reproduce and distribute copies of the | ||||
|       Work or Derivative Works thereof in any medium, with or without | ||||
|       modifications, and in Source or Object form, provided that You | ||||
|       meet the following conditions: | ||||
| 
 | ||||
|       (a) You must give any other recipients of the Work or | ||||
|           Derivative Works a copy of this License; and | ||||
| 
 | ||||
|       (b) You must cause any modified files to carry prominent notices | ||||
|           stating that You changed the files; and | ||||
| 
 | ||||
|       (c) You must retain, in the Source form of any Derivative Works | ||||
|           that You distribute, all copyright, patent, trademark, and | ||||
|           attribution notices from the Source form of the Work, | ||||
|           excluding those notices that do not pertain to any part of | ||||
|           the Derivative Works; and | ||||
| 
 | ||||
|       (d) If the Work includes a "NOTICE" text file as part of its | ||||
|           distribution, then any Derivative Works that You distribute must | ||||
|           include a readable copy of the attribution notices contained | ||||
|           within such NOTICE file, excluding those notices that do not | ||||
|           pertain to any part of the Derivative Works, in at least one | ||||
|           of the following places: within a NOTICE text file distributed | ||||
|           as part of the Derivative Works; within the Source form or | ||||
|           documentation, if provided along with the Derivative Works; or, | ||||
|           within a display generated by the Derivative Works, if and | ||||
|           wherever such third-party notices normally appear. The contents | ||||
|           of the NOTICE file are for informational purposes only and | ||||
|           do not modify the License. You may add Your own attribution | ||||
|           notices within Derivative Works that You distribute, alongside | ||||
|           or as an addendum to the NOTICE text from the Work, provided | ||||
|           that such additional attribution notices cannot be construed | ||||
|           as modifying the License. | ||||
| 
 | ||||
|       You may add Your own copyright statement to Your modifications and | ||||
|       may provide additional or different license terms and conditions | ||||
|       for use, reproduction, or distribution of Your modifications, or | ||||
|       for any such Derivative Works as a whole, provided Your use, | ||||
|       reproduction, and distribution of the Work otherwise complies with | ||||
|       the conditions stated in this License. | ||||
| 
 | ||||
|    5. Submission of Contributions. Unless You explicitly state otherwise, | ||||
|       any Contribution intentionally submitted for inclusion in the Work | ||||
|       by You to the Licensor shall be under the terms and conditions of | ||||
|       this License, without any additional terms or conditions. | ||||
|       Notwithstanding the above, nothing herein shall supersede or modify | ||||
|       the terms of any separate license agreement you may have executed | ||||
|       with Licensor regarding such Contributions. | ||||
| 
 | ||||
|    6. Trademarks. This License does not grant permission to use the trade | ||||
|       names, trademarks, service marks, or product names of the Licensor, | ||||
|       except as required for reasonable and customary use in describing the | ||||
|       origin of the Work and reproducing the content of the NOTICE file. | ||||
| 
 | ||||
|    7. Disclaimer of Warranty. Unless required by applicable law or | ||||
|       agreed to in writing, Licensor provides the Work (and each | ||||
|       Contributor provides its Contributions) on an "AS IS" BASIS, | ||||
|       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||||
|       implied, including, without limitation, any warranties or conditions | ||||
|       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | ||||
|       PARTICULAR PURPOSE. You are solely responsible for determining the | ||||
|       appropriateness of using or redistributing the Work and assume any | ||||
|       risks associated with Your exercise of permissions under this License. | ||||
| 
 | ||||
|    8. Limitation of Liability. In no event and under no legal theory, | ||||
|       whether in tort (including negligence), contract, or otherwise, | ||||
|       unless required by applicable law (such as deliberate and grossly | ||||
|       negligent acts) or agreed to in writing, shall any Contributor be | ||||
|       liable to You for damages, including any direct, indirect, special, | ||||
|       incidental, or consequential damages of any character arising as a | ||||
|       result of this License or out of the use or inability to use the | ||||
|       Work (including but not limited to damages for loss of goodwill, | ||||
|       work stoppage, computer failure or malfunction, or any and all | ||||
|       other commercial damages or losses), even if such Contributor | ||||
|       has been advised of the possibility of such damages. | ||||
| 
 | ||||
|    9. Accepting Warranty or Additional Liability. While redistributing | ||||
|       the Work or Derivative Works thereof, You may choose to offer, | ||||
|       and charge a fee for, acceptance of support, warranty, indemnity, | ||||
|       or other liability obligations and/or rights consistent with this | ||||
|       License. However, in accepting such obligations, You may act only | ||||
|       on Your own behalf and on Your sole responsibility, not on behalf | ||||
|       of any other Contributor, and only if You agree to indemnify, | ||||
|       defend, and hold each Contributor harmless for any liability | ||||
|       incurred by, or claims asserted against, such Contributor by reason | ||||
|       of your accepting any such warranty or additional liability. | ||||
| 
 | ||||
|    END OF TERMS AND CONDITIONS | ||||
| 
 | ||||
|    APPENDIX: How to apply the Apache License to your work. | ||||
| 
 | ||||
|       To apply the Apache License to your work, attach the following | ||||
|       boilerplate notice, with the fields enclosed by brackets "{}" | ||||
|       replaced with your own identifying information. (Don't include | ||||
|       the brackets!)  The text should be enclosed in the appropriate | ||||
|       comment syntax for the file format. We also recommend that a | ||||
|       file or class name and description of purpose be included on the | ||||
|       same "printed page" as the copyright notice for easier | ||||
|       identification within third-party archives. | ||||
| 
 | ||||
|    Copyright (C) 2012-present   SheetJS LLC | ||||
| 
 | ||||
|    Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|    you may not use this file except in compliance with the License. | ||||
|    You may obtain a copy of the License at | ||||
| 
 | ||||
|        http://www.apache.org/licenses/LICENSE-2.0 | ||||
| 
 | ||||
|    Unless required by applicable law or agreed to in writing, software | ||||
|    distributed under the License is distributed on an "AS IS" BASIS, | ||||
|    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|    See the License for the specific language governing permissions and | ||||
|    limitations under the License. | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
							
								
								
									
										46
									
								
								docz/docs/09-miscellany/09-references.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,46 @@ | ||||
| --- | ||||
| sidebar_position: 9 | ||||
| hide_table_of_contents: true | ||||
| --- | ||||
| 
 | ||||
| # References | ||||
| 
 | ||||
| Some of our original research is documented at <https://oss.sheetjs.com/notes/> | ||||
| 
 | ||||
| The specifications list is non-exhaustive. | ||||
| 
 | ||||
| - ISO/IEC 29500:2012(E) "Information technology — Document description and processing languages — Office Open XML File Formats" | ||||
| - Open Document Format for Office Applications Version 1.2 (29 September 2011) | ||||
| - Worksheet File Format (From Lotus) December 1984 | ||||
| 
 | ||||
| 
 | ||||
| ## Open Specifications Promise | ||||
| 
 | ||||
| Lotus released their "Worksheet File Format" documentation into the Public | ||||
| Domain.  Microsoft opted for the "Open Specifications Promise", a covenant not | ||||
| to sue.  The documentation that falls under the promise are listed below. | ||||
| 
 | ||||
| <details><summary><b>Specifications</b> (click to show)</summary> | ||||
| 
 | ||||
|  - `MS-CFB`: Compound File Binary File Format | ||||
|  - `MS-CTXLS`: Excel Custom Toolbar Binary File Format | ||||
|  - `MS-EXSPXML3`: Excel Calculation Version 2 Web Service XML Schema | ||||
|  - `MS-ODATA`: Open Data Protocol (OData) | ||||
|  - `MS-ODRAW`: Office Drawing Binary File Format | ||||
|  - `MS-ODRAWXML`: Office Drawing Extensions to Office Open XML Structure | ||||
|  - `MS-OE376`: Office Implementation Information for ECMA-376 Standards Support | ||||
|  - `MS-OFFCRYPTO`: Office Document Cryptography Structure | ||||
|  - `MS-OI29500`: Office Implementation Information for ISO/IEC 29500 Standards Support | ||||
|  - `MS-OLEDS`: Object Linking and Embedding (OLE) Data Structures | ||||
|  - `MS-OLEPS`: Object Linking and Embedding (OLE) Property Set Data Structures | ||||
|  - `MS-OODF3`: Office Implementation Information for ODF 1.2 Standards Support | ||||
|  - `MS-OSHARED`: Office Common Data Types and Objects Structures | ||||
|  - `MS-OVBA`: Office VBA File Format Structure | ||||
|  - `MS-XLDM`: Spreadsheet Data Model File Format | ||||
|  - `MS-XLS`: Excel Binary File Format (.xls) Structure Specification | ||||
|  - `MS-XLSB`: Excel (.xlsb) Binary File Format | ||||
|  - `MS-XLSX`: Excel (.xlsx) Extensions to the Office Open XML SpreadsheetML File Format | ||||
|  - `XLS`: Microsoft Office Excel 97-2007 Binary File Format Specification | ||||
|  - `RTF`: Rich Text Format | ||||
| 
 | ||||
| </details> | ||||
							
								
								
									
										4
									
								
								docz/docs/09-miscellany/_category_.json
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,4 @@ | ||||
| { | ||||
|   "label": "Miscellany", | ||||
|   "position": 9 | ||||
| } | ||||
							
								
								
									
										
											BIN
										
									
								
								docz/docs/img/final.png
									
									
									
									
									
										Normal file
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						| After Width: | Height: | Size: 32 KiB | 
							
								
								
									
										
											BIN
										
									
								
								docz/docs/img/formats.png
									
									
									
									
									
										Normal file
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						| After Width: | Height: | Size: 204 KiB | 
							
								
								
									
										
											BIN
										
									
								
								docz/docs/img/legend.png
									
									
									
									
									
										Normal file
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						| After Width: | Height: | Size: 33 KiB | 
							
								
								
									
										
											BIN
										
									
								
								docz/docs/img/rough.png
									
									
									
									
									
										Normal file
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						| After Width: | Height: | Size: 28 KiB | 
							
								
								
									
										38
									
								
								docz/docs/img/tools.svg
									
									
									
									
									
										Normal file
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,38 @@ | ||||
| <svg width="100%" height="100%" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"> | ||||
|   <polygon fill="#ffffff" points="0,0 0,1024 1024,1024 1024,0"/> | ||||
|   <g> | ||||
|     <rect x="320" y="128" width="384" height="136" fill="#ffffff" stroke="#000000" stroke-width="8" rx="16"/> | ||||
|     <rect x="384" y="192" width="256" height="64" fill="#ffffff" stroke="#000000" stroke-width="8" rx="16"/> | ||||
|     <rect x="128" y="256" width="768" height="192" fill="#ffffff" stroke="#000000" stroke-width="8"/> | ||||
|     <rect x="128" y="448" width="768" height="448" fill="#ffffff" stroke="#000000" stroke-width="8"/> | ||||
|     <rect x="384" y="384" width="256" height="256" fill="#ffffff" stroke="#000000" stroke-width="8"/> | ||||
|   </g> | ||||
|   <g transform="translate(416,416) scale(0.1875 0.1875)"> | ||||
|     <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" /> | ||||
|     </svg> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 2.5 KiB | 
							
								
								
									
										223
									
								
								docz/docs/index.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,223 @@ | ||||
| --- | ||||
| sidebar_position: 1 | ||||
| hide_table_of_contents: true | ||||
| --- | ||||
| 
 | ||||
| # SheetJS CE | ||||
| 
 | ||||
|  | ||||
| [](https://github.com/SheetJS/sheetjs/actions) | ||||
| [](https://snyk.io/test/github/SheetJS/sheetjs) | ||||
| [](https://npmjs.org/package/xlsx) | ||||
| 
 | ||||
| SheetJS Community Edition offers battle-tested open-source solutions for | ||||
| extracting useful data from almost any complex spreadsheet and generating new | ||||
| spreadsheets that will work with legacy and modern software alike. | ||||
| 
 | ||||
| [SheetJS Pro](https://sheetjs.com/pro) offers solutions beyond data processing: | ||||
| Edit complex templates with ease; let out your inner Picasso with styling; make | ||||
| custom sheets with images/graphs/PivotTables; evaluate formula expressions and | ||||
| port calculations to web apps; automate common spreadsheet tasks, and much more! | ||||
| 
 | ||||
| ## Simple Examples | ||||
| 
 | ||||
| The code editors are live -- feel free to edit!  Due to technical limitations, | ||||
| they showcase ReactJS patterns.  Other parts of the documentation will cover | ||||
| more common use cases including plain JavaScript. | ||||
| 
 | ||||
| ### Export an HTML Table to Excel XLSX | ||||
| 
 | ||||
| <details><summary><b>How to add to your site</b> (click to show)</summary> | ||||
| 
 | ||||
| 1) Make sure your table has an ID: | ||||
| 
 | ||||
| ```html | ||||
| <table id="TableToExport"> | ||||
| ``` | ||||
| 
 | ||||
| 2) Include a reference to the SheetJS Library in your page: | ||||
| 
 | ||||
| ```html | ||||
| <script src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"></script> | ||||
| ``` | ||||
| 
 | ||||
| 3) Add a button that users will click to generate an export | ||||
| 
 | ||||
| ```html | ||||
| <button id="sheetjsexport"><b>Export as XLSX</b></button> | ||||
| ``` | ||||
| 
 | ||||
| 4) Add an event handler for the `click` event to create a workbook and download: | ||||
| 
 | ||||
| ```js | ||||
| document.getElementById("TableToExport").addEventListener('click', function() { | ||||
|   /* Create worksheet from HTML DOM TABLE */ | ||||
|   var wb = XLSX.utils.table_to_book(document.getElementById("TableToExport")); | ||||
|   /* Export to file (start a download) */ | ||||
|   XLSX.writeFile(wb, "SheetJSTable.xlsx"); | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details open><summary><b>Live Example</b> (click to show)</summary> | ||||
| 
 | ||||
| ```jsx live | ||||
| /* The live editor requires this function wrapper */ | ||||
| function Table2XLSX(props) { | ||||
| 
 | ||||
|   /* Callback invoked when the button is clicked */ | ||||
|   const xport = React.useCallback(() => { | ||||
|       /* Create worksheet from HTML DOM TABLE */ | ||||
|       const table = document.getElementById("Table2XLSX"); | ||||
|       const wb = XLSX.utils.table_to_book(table); | ||||
| 
 | ||||
|       /* Export to file (start a download) */ | ||||
|       XLSX.writeFile(wb, "SheetJSTable.xlsx"); | ||||
|   }); | ||||
| 
 | ||||
|   return (<> | ||||
|     <table id="Table2XLSX"><tbody> | ||||
|       <tr><td colSpan="3">SheetJS Table Export</td></tr> | ||||
|       <tr><td>Author</td><td>ID</td><td>Note</td></tr> | ||||
|       <tr><td>SheetJS</td><td>7262</td><td>Hi!</td></tr> | ||||
|       <tr><td colSpan="3"> | ||||
|         <a href="//sheetjs.com">Powered by SheetJS</a> | ||||
|       </td></tr> | ||||
|     </tbody></table> | ||||
|     <button onClick={xport}><b>Export XLSX!</b></button> | ||||
|   </>); | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| <a href="https://sheetjs.com/pro">SheetJS Pro Basic</a> extends this export with | ||||
| support for CSS styling and rich text. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ### Download and Preview a Numbers workbook | ||||
| 
 | ||||
| <details><summary><b>How to add to your site</b> (click to show)</summary> | ||||
| 
 | ||||
| 1) Create a container DIV for the table: | ||||
| 
 | ||||
| ```html | ||||
| <div id="TableContainer"></div> | ||||
| ``` | ||||
| 
 | ||||
| 2) Include a reference to the SheetJS Library in your page: | ||||
| 
 | ||||
| ```html | ||||
| <script src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"></script> | ||||
| ``` | ||||
| 
 | ||||
| 3) Add a script block to download and update the page: | ||||
| 
 | ||||
| ```html | ||||
| <script> | ||||
| (async() => { | ||||
|   const f = await fetch(URL_TO_DOWNLOAD); // replace with the URL of the file | ||||
|   const ab = await f.arrayBuffer(); | ||||
| 
 | ||||
|   /* Parse file and get first worksheet */ | ||||
|   const wb = XLSX.read(ab); | ||||
|   const ws = wb.Sheets[wb.SheetNames[0]]; | ||||
| 
 | ||||
|   /* Generate HTML */ | ||||
|   var output = document.getElementById("TableContainer"); | ||||
|   output.innerHTML = XLSX.utils.sheet_to_html(ws); | ||||
| })(); | ||||
| </script> | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details><summary><b>Live Example</b> (click to hide)</summary> | ||||
| 
 | ||||
| ```jsx live | ||||
| /* The live editor requires this function wrapper */ | ||||
| function Numbers2HTML(props) { | ||||
|   const [html, setHTML] = React.useState(""); | ||||
| 
 | ||||
|   /* Fetch and update HTML */ | ||||
|   React.useEffect(async() => { | ||||
|     /* Fetch file */ | ||||
|     const f = await fetch("https://sheetjs.com/pres.numbers"); | ||||
|     const ab = await f.arrayBuffer(); | ||||
| 
 | ||||
|     /* Parse file */ | ||||
|     const wb = XLSX.read(ab); | ||||
|     const ws = wb.Sheets[wb.SheetNames[0]]; | ||||
| 
 | ||||
|     /* Generate HTML */ | ||||
|     setHTML(XLSX.utils.sheet_to_html(ws)); | ||||
|   }); | ||||
| 
 | ||||
|   return (<div dangerouslySetInnerHTML={{__html: html}}/>); | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| <a href="https://sheetjs.com/pro">SheetJS Pro Basic</a> extends this import with | ||||
| support for CSS styling and rich text. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ### Convert a CSV file to HTML Table and Excel XLSX | ||||
| 
 | ||||
| <details><summary><b>Live Example</b> (click to show)</summary> | ||||
| 
 | ||||
| ```jsx live | ||||
| /* The live editor requires this function wrapper */ | ||||
| function Tabeller(props) { | ||||
| 
 | ||||
|   /* Starting CSV data -- change data here */ | ||||
|   const csv = `\ | ||||
| This,is,a,Test | ||||
| வணக்கம்,สวัสดี,你好,가지마 | ||||
| 1,2,3,4`; | ||||
| 
 | ||||
|   /* Parse CSV into a workbook object */ | ||||
|   const wb = XLSX.read(csv, {type: "string"}); | ||||
| 
 | ||||
|   /* Get the worksheet (default name "Sheet1") */ | ||||
|   const ws = wb.Sheets.Sheet1; | ||||
| 
 | ||||
|   /* Create HTML table */ | ||||
|   const id = "tabeller"; // HTML TABLE ID | ||||
|   const __html = XLSX.utils.sheet_to_html(ws, { id }); | ||||
| 
 | ||||
|   return (<> | ||||
| 
 | ||||
|     {/* Show HTML preview */} | ||||
|     <div dangerouslySetInnerHTML={{__html}}/> | ||||
| 
 | ||||
|     {/* Export Button */} | ||||
|     <button onClick={() => { | ||||
| 
 | ||||
|       /* Create worksheet from HTML DOM TABLE */ | ||||
|       const table = document.getElementById(id); | ||||
|       const wb = XLSX.utils.table_to_book(table); | ||||
| 
 | ||||
|       /* Export to file (start a download) */ | ||||
|       XLSX.writeFile(wb, "SheetJSIntro.xlsx"); | ||||
|     }}> | ||||
|       <b>Export XLSX!</b> | ||||
|     </button> | ||||
| 
 | ||||
|   </>); | ||||
| 
 | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| 
 | ||||
| ### Browser Testing | ||||
| 
 | ||||
| [](https://saucelabs.com/u/sheetjs) | ||||
| 
 | ||||
| ### Supported File Formats | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										161
									
								
								docz/docusaurus.config.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,161 @@ | ||||
| // @ts-check
 | ||||
| // Note: type annotations allow type checking and IDEs autocompletion
 | ||||
| 
 | ||||
| const lightCodeTheme = require('prism-react-renderer/themes/github'); | ||||
| const darkCodeTheme = require('prism-react-renderer/themes/dracula'); | ||||
| 
 | ||||
| /** @type {import('@docusaurus/types').Config} */ | ||||
| const config = { | ||||
|   title: 'SheetJS Community Edition', | ||||
|   tagline: 'Get Sheet Done', | ||||
|   url: 'https://docs.sheetjs.com', | ||||
|   baseUrl: '/', | ||||
|   onBrokenLinks: 'throw', | ||||
|   onBrokenMarkdownLinks: 'warn', | ||||
|   favicon: 'img/favicon.ico', | ||||
| 
 | ||||
|   // GitHub pages deployment config.
 | ||||
|   // If you aren't using GitHub pages, you don't need these.
 | ||||
|   //organizationName: 'sheetjs', // Usually your GitHub org/user name.
 | ||||
|   //projectName: 'sheetjs', // Usually your repo name.
 | ||||
| 
 | ||||
|   // Even if you don't use internalization, you can use this field to set useful
 | ||||
|   // metadata like html lang. For example, if your site is Chinese, you may want
 | ||||
|   // to replace "en" with "zh-Hans".
 | ||||
|   i18n: { | ||||
|     defaultLocale: 'en', | ||||
|     locales: ['en'], | ||||
|   }, | ||||
| 
 | ||||
|   presets: [ | ||||
|     [ | ||||
|       'classic', | ||||
|       /** @type {import('@docusaurus/preset-classic').Options} */ | ||||
|       ({ | ||||
|         docs: { | ||||
|           sidebarPath: require.resolve('./sidebars.js'), | ||||
|           // Please change this to your repo.
 | ||||
|           // Remove this to remove the "edit this page" links.
 | ||||
|           // editUrl:
 | ||||
|             // 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/',
 | ||||
|         }, | ||||
|         //blog: {
 | ||||
|         //  showReadingTime: true,
 | ||||
|           // Please change this to your repo.
 | ||||
|           // Remove this to remove the "edit this page" links.
 | ||||
|           // editUrl:
 | ||||
|             // 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/',
 | ||||
|         //},
 | ||||
|         theme: { | ||||
|           customCss: require.resolve('./src/css/custom.css'), | ||||
|         }, | ||||
|         googleAnalytics: { | ||||
|           trackingID: 'UA-36810333-1', | ||||
|           anonymizeIP: true | ||||
|         } | ||||
|       }), | ||||
|     ], | ||||
|   ], | ||||
| 
 | ||||
|   themeConfig: | ||||
|     /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ | ||||
|     ({ | ||||
|       navbar: { | ||||
|         title: 'SheetJS CE Docs', | ||||
|         logo: { | ||||
|           alt: 'SheetJS Logo', | ||||
|           src: 'img/logo.svg', | ||||
|         }, | ||||
|         items: [ | ||||
|           { | ||||
|             type: 'doc', | ||||
|             docId: 'index', | ||||
|             position: 'left', | ||||
|             label: 'Docs', | ||||
|           }, | ||||
|           //{to: '/blog', label: 'Blog', position: 'left'},
 | ||||
|           { | ||||
|             href: 'https://sheetjs.com', | ||||
|             label: 'SheetJS', | ||||
|             position: 'right', | ||||
|           }, | ||||
|           { | ||||
|             href: 'https://github.com/sheetjs/sheetjs', | ||||
|             label: 'Source', | ||||
|             position: 'right', | ||||
|           }, | ||||
|         ], | ||||
|       }, | ||||
|       footer: { | ||||
|         style: 'dark', | ||||
|         links: [ | ||||
|           { | ||||
|             title: 'Docs', | ||||
|             items: [ | ||||
|               { | ||||
|                 label: 'Intro', | ||||
|                 to: '/docs', | ||||
|               }, | ||||
|               { | ||||
|                 label: 'Example', | ||||
|                 to: '/docs/example', | ||||
|               }, | ||||
|             ], | ||||
|           }, | ||||
|           { | ||||
|             title: 'Community', | ||||
|             items: [ | ||||
|               //{
 | ||||
|               //  label: 'Stack Overflow',
 | ||||
|               //  href: 'https://stackoverflow.com/questions/tagged/sheetjs',
 | ||||
|               //},
 | ||||
|               //{
 | ||||
|               //  label: 'Discord',
 | ||||
|               //  href: 'https://discordapp.com/invite/sheetjs',
 | ||||
|               //},
 | ||||
|               { | ||||
|                 label: 'Twitter', | ||||
|                 href: 'https://twitter.com/sheetjs', | ||||
|               }, | ||||
|             ], | ||||
|           }, | ||||
|           { | ||||
|             title: 'More', | ||||
|             items: [ | ||||
|               //{
 | ||||
|               //  label: 'Blog',
 | ||||
|               //  to: '/blog',
 | ||||
|               //},
 | ||||
|               { | ||||
|                 label: 'SheetJS Pro', | ||||
|                 href: 'https://sheetjs.com/pro', | ||||
|               }, | ||||
|               { | ||||
|                 label: 'Source', | ||||
|                 href: 'https://github.com/sheetjs/sheetjs', | ||||
|               }, | ||||
|             ], | ||||
|           }, | ||||
|         ], | ||||
|         copyright: `Copyright © ${new Date().getFullYear()} SheetJS LLC.`, | ||||
|       }, | ||||
|       prism: { | ||||
|         theme: lightCodeTheme, | ||||
|         darkTheme: darkCodeTheme, | ||||
|       }, | ||||
|       liveCodeBlock: { | ||||
|         playgroundPosition: 'top' | ||||
|       } | ||||
|     }), | ||||
|   themes: [ | ||||
|     "@docusaurus/theme-live-codeblock" | ||||
|   ], | ||||
|   scripts: [ | ||||
|     { | ||||
|       src: "https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js", | ||||
|       async: true | ||||
|     } | ||||
|   ] | ||||
| }; | ||||
| 
 | ||||
| module.exports = config; | ||||
							
								
								
									
										43
									
								
								docz/package.json
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,43 @@ | ||||
| { | ||||
|   "name": "docs", | ||||
|   "version": "0.0.0", | ||||
|   "private": true, | ||||
|   "scripts": { | ||||
|     "docusaurus": "docusaurus", | ||||
|     "start": "docusaurus start", | ||||
|     "build": "docusaurus build", | ||||
|     "swizzle": "docusaurus swizzle", | ||||
|     "deploy": "docusaurus deploy", | ||||
|     "clear": "docusaurus clear", | ||||
|     "serve": "docusaurus serve", | ||||
|     "write-translations": "docusaurus write-translations", | ||||
|     "write-heading-ids": "docusaurus write-heading-ids" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@docusaurus/core": "2.0.0-beta.20", | ||||
|     "@docusaurus/preset-classic": "2.0.0-beta.20", | ||||
|     "@docusaurus/theme-common": "^2.0.0-beta.20", | ||||
|     "@docusaurus/theme-live-codeblock": "^2.0.0-beta.20", | ||||
|     "@mdx-js/react": "^1.6.22", | ||||
|     "clsx": "^1.1.1", | ||||
|     "prism-react-renderer": "^1.3.1", | ||||
|     "react": "^17.0.2", | ||||
|     "react-dom": "^17.0.2", | ||||
|     "xlsx": "https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@docusaurus/module-type-aliases": "2.0.0-beta.20" | ||||
|   }, | ||||
|   "browserslist": { | ||||
|     "production": [ | ||||
|       ">0.5%", | ||||
|       "not dead", | ||||
|       "not op_mini all" | ||||
|     ], | ||||
|     "development": [ | ||||
|       "last 1 chrome version", | ||||
|       "last 1 firefox version", | ||||
|       "last 1 safari version" | ||||
|     ] | ||||
|   } | ||||
| } | ||||
							
								
								
									
										31
									
								
								docz/sidebars.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,31 @@ | ||||
| /** | ||||
|  * Creating a sidebar enables you to: | ||||
|  - create an ordered group of docs | ||||
|  - render a sidebar for each doc of that group | ||||
|  - provide next/previous navigation | ||||
| 
 | ||||
|  The sidebars can be generated from the filesystem, or explicitly defined here. | ||||
| 
 | ||||
|  Create as many sidebars as you want. | ||||
|  */ | ||||
| 
 | ||||
| // @ts-check
 | ||||
| 
 | ||||
| /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ | ||||
| const sidebars = { | ||||
|   // By default, Docusaurus generates a sidebar from the docs folder structure
 | ||||
|   tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], | ||||
| 
 | ||||
|   // But you can create a sidebar manually
 | ||||
|   /* | ||||
|   tutorialSidebar: [ | ||||
|     { | ||||
|       type: 'category', | ||||
|       label: 'Tutorial', | ||||
|       items: ['hello'], | ||||
|     }, | ||||
|   ], | ||||
|    */ | ||||
| }; | ||||
| 
 | ||||
| module.exports = sidebars; | ||||
							
								
								
									
										93
									
								
								docz/src/components/HomepageFeatures/index.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,93 @@ | ||||
| import React from 'react'; | ||||
| import clsx from 'clsx'; | ||||
| import styles from './styles.module.css'; | ||||
| import Link from '@docusaurus/Link'; | ||||
| 
 | ||||
| const FeatureList = [ | ||||
|   { | ||||
|     title: 'All the Data', | ||||
|     Svg: require('@site/static/img/data.svg').default, | ||||
|     description: ( | ||||
|       <> | ||||
|         SheetJS presents a unified interface to every Excel file format as well | ||||
|         as Lotus 1-2-3, Numbers, and Quattro Pro.  Process all the data! | ||||
|       </> | ||||
|     ), | ||||
|     denouement: ( | ||||
|       <div className={styles.buttons}> | ||||
|         <Link | ||||
|           className="button button--secondary button--lg" | ||||
|           to="/docs/miscellany/formats"> | ||||
|           File Details | ||||
|         </Link> | ||||
|       </div> | ||||
|     ), | ||||
|   }, | ||||
|   { | ||||
|     title: 'All the Tools', | ||||
|     Svg: require('@site/static/img/tools.svg').default, | ||||
|     description: ( | ||||
|       <> | ||||
|         SheetJS offers solutions for common data problems.  Unlock the power of | ||||
|         JavaScript to wrangle data and effortlessly solve problems. | ||||
|       </> | ||||
|     ), | ||||
|     denouement: ( | ||||
|       <div className={styles.buttons}> | ||||
|         <Link | ||||
|           className="button button--secondary button--lg" | ||||
|           to="/docs/example"> | ||||
|           Complete Example | ||||
|         </Link> | ||||
|       </div> | ||||
|     ), | ||||
|   }, | ||||
|   { | ||||
|     title: 'All the Places', | ||||
|     Svg: require('@site/static/img/places.svg').default, | ||||
|     description: ( | ||||
|       <> | ||||
|         SheetJS runs everywhere: web browsers, servers, desktop apps, mobile | ||||
|         apps, SalesForce and Photoshop plugins, even within Excel! | ||||
|       </> | ||||
|     ), | ||||
|     denouement: ( | ||||
|       <div className={styles.buttons}> | ||||
|         <Link | ||||
|           className="button button--secondary button--lg" | ||||
|           to="/docs/getting-started/demos"> | ||||
|           Demo Projects | ||||
|         </Link> | ||||
|       </div> | ||||
|     ), | ||||
|   }, | ||||
| ]; | ||||
| 
 | ||||
| function Feature({Svg, title, description, denouement}) { | ||||
|   return ( | ||||
|     <div className={clsx('col col--4')}> | ||||
|       <div className="text--center"> | ||||
|         <Svg className={styles.featureSvg} role="img" /> | ||||
|       </div> | ||||
|       <div className="text--center padding-horiz--md"> | ||||
|         <h3>{title}</h3> | ||||
|         <p>{description}</p> | ||||
|       </div> | ||||
|       {denouement && (<div className="text--center">{denouement}</div>)} | ||||
|     </div> | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export default function HomepageFeatures() { | ||||
|   return ( | ||||
|     <section className={styles.features}> | ||||
|       <div className="container"> | ||||
|         <div className="row"> | ||||
|           {FeatureList.map((props, idx) => ( | ||||
|             <Feature key={idx} {...props} /> | ||||
|           ))} | ||||
|         </div> | ||||
|       </div> | ||||
|     </section> | ||||
|   ); | ||||
| } | ||||
							
								
								
									
										11
									
								
								docz/src/components/HomepageFeatures/styles.module.css
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,11 @@ | ||||
| .features { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   padding: 2rem 0; | ||||
|   width: 100%; | ||||
| } | ||||
| 
 | ||||
| .featureSvg { | ||||
|   height: 200px; | ||||
|   width: 200px; | ||||
| } | ||||
							
								
								
									
										40
									
								
								docz/src/components/Playground.tsx
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,40 @@ | ||||
| import React from 'react'; | ||||
| import useBaseUrl from '@docusaurus/useBaseUrl'; | ||||
| 
 | ||||
| import { CodePreview } from 'docusaurus-plugin-code-preview'; | ||||
| 
 | ||||
| /* | ||||
| export default function Playground(props) { | ||||
|   return ( | ||||
|     <CodePreview | ||||
|       output={{ | ||||
|         outputs: [ | ||||
|           { | ||||
|             name: 'JavaScript', | ||||
|             value: 'javascript', | ||||
|           }, | ||||
|           { | ||||
|             name: 'React', | ||||
|             value: 'react', | ||||
|           }, | ||||
|           { | ||||
|             name: 'Angular', | ||||
|             value: 'angular', | ||||
|           }, | ||||
|           { | ||||
|             name: 'Vue', | ||||
|             value: 'vue', | ||||
|           }, | ||||
|         ], | ||||
|         // This is the default selected option in the rendered component
 | ||||
|         defaultOutput: 'javascript', | ||||
|       }} | ||||
|       // Your existing options
 | ||||
|     /> | ||||
|   ); | ||||
| } | ||||
| */ | ||||
| 
 | ||||
| export default function Playground(props) { | ||||
|   return <CodePreview {...props} src={useBaseUrl(props.src)} />; | ||||
| } | ||||
							
								
								
									
										39
									
								
								docz/src/css/custom.css
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,39 @@ | ||||
| /** | ||||
|  * Any CSS included here will be global. The classic template | ||||
|  * bundles Infima by default. Infima is a CSS framework designed to | ||||
|  * work well for content-centric websites. | ||||
|  */ | ||||
| 
 | ||||
| /* You can override the default Infima variables here. */ | ||||
| :root { | ||||
|   --ifm-color-primary: #25c2a0; | ||||
|   --ifm-color-primary-dark: #40b48a; | ||||
|   --ifm-color-primary-darker: #3c9e7a; | ||||
|   --ifm-color-primary-darkest: #3c9e7a; | ||||
|   --ifm-color-primary-light: #58e0ae; | ||||
|   --ifm-color-primary-lighter: #8ef5cf; | ||||
|   --ifm-color-primary-lightest: #8ef5cf; | ||||
|   --ifm-code-font-size: 95%; | ||||
|   --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); | ||||
| } | ||||
| 
 | ||||
| /* For readability concerns, you should choose a lighter palette in dark mode. */ | ||||
| [data-theme='dark'] { | ||||
|   --ifm-color-primary: #25c2a0; | ||||
|   --ifm-color-primary-dark: #21af90; | ||||
|   --ifm-color-primary-darker: #1fa588; | ||||
|   --ifm-color-primary-darkest: #4db69f; | ||||
|   --ifm-color-primary-light: #29d5b0; | ||||
|   --ifm-color-primary-lighter: #32d8b4; | ||||
|   --ifm-color-primary-lightest: #4fddbf; | ||||
|   --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); | ||||
| } | ||||
| 
 | ||||
| .content-pack::before { | ||||
|   content: "\1f4e6"; | ||||
|   margin-left: -20px; | ||||
|   margin-right: 4px; | ||||
| } | ||||
| .content-pack { | ||||
|   position: relative; | ||||
| } | ||||
							
								
								
									
										40
									
								
								docz/src/pages/index.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,40 @@ | ||||
| import React from 'react'; | ||||
| import clsx from 'clsx'; | ||||
| import Layout from '@theme/Layout'; | ||||
| import Link from '@docusaurus/Link'; | ||||
| import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; | ||||
| import styles from './index.module.css'; | ||||
| import HomepageFeatures from '@site/src/components/HomepageFeatures'; | ||||
| 
 | ||||
| function HomepageHeader() { | ||||
|   const {siteConfig} = useDocusaurusContext(); | ||||
|   return ( | ||||
|     <header className={clsx('hero hero--primary', styles.heroBanner)}> | ||||
|       <div className="container"> | ||||
|         <h1 className="hero__title">{siteConfig.title}</h1> | ||||
|         <p className="hero__subtitle">{siteConfig.tagline}</p> | ||||
|         <div className={styles.buttons}> | ||||
|           <Link | ||||
|             className="button button--secondary button--lg" | ||||
|             to="/docs"> | ||||
|             Get Started | ||||
|           </Link> | ||||
|         </div> | ||||
|       </div> | ||||
|     </header> | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export default function Home() { | ||||
|   const {siteConfig} = useDocusaurusContext(); | ||||
|   return ( | ||||
|     <Layout | ||||
|       title={siteConfig.title} | ||||
|       description="SheetJS Community Edition Documentation"> | ||||
|       <HomepageHeader /> | ||||
|       <main> | ||||
|         <HomepageFeatures /> | ||||
|       </main> | ||||
|     </Layout> | ||||
|   ); | ||||
| } | ||||
							
								
								
									
										23
									
								
								docz/src/pages/index.module.css
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,23 @@ | ||||
| /** | ||||
|  * CSS files with the .module.css suffix will be treated as CSS modules | ||||
|  * and scoped locally. | ||||
|  */ | ||||
| 
 | ||||
| .heroBanner { | ||||
|   padding: 4rem 0; | ||||
|   text-align: center; | ||||
|   position: relative; | ||||
|   overflow: hidden; | ||||
| } | ||||
| 
 | ||||
| @media screen and (max-width: 996px) { | ||||
|   .heroBanner { | ||||
|     padding: 2rem; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .buttons { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   justify-content: center; | ||||
| } | ||||
							
								
								
									
										0
									
								
								docz/static/.nojekyll
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
							
								
								
									
										2364
									
								
								docz/static/data.json
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
							
								
								
									
										41
									
								
								docz/static/img/data.svg
									
									
									
									
									
										Normal file
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,41 @@ | ||||
| <svg width="100%" height="100%" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"> | ||||
|   <polygon fill="#ffffff" points="0,0 0,1024 1024,1024 1024,0"/> | ||||
|   <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" x="64" y="384" height="256" width="256"> | ||||
|     <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> | ||||
|   <svg viewBox="-100 -100 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" x="384" y="384" width="256" height="256"> | ||||
|     <path transform="translate(160,320) rotate(225)" d="M0,0v200a100,100,90,0,0,200,0a100,100,90,0,0,0,-200z" fill="transparent" stroke="#E4187A" stroke-width="16"/> | ||||
|   </svg> | ||||
|   <svg xmlns="http://www.w3.org/2000/svg" viewBox="112 0 1024 1024" x="704" y="384" width="256" height="256"> | ||||
|     <path d="M128,16h480l256,256v736h-736z" fill="transparent" stroke="#000000" stroke-width="16" /> | ||||
|     <path d="M608,16l256,256h-256z" fill="transparent" stroke="#000000" stroke-width="16" stroke-linejoin="round" /> | ||||
|     <rect x="220" y="348" width="552" height="552" fill="transparent" stroke="#000000" stroke-width="16"/> | ||||
|     <line x1="220" y1="486" x2="772" y2="486" stroke="#000000" stroke-width="8" /> | ||||
|     <line x1="220" y1="624" x2="772" y2="624" stroke="#000000" stroke-width="8" /> | ||||
|     <line x1="220" y1="762" x2="772" y2="762" stroke="#000000" stroke-width="8" /> | ||||
|     <line x1="496" y1="348" x2="496" y2="900" stroke="#000000" stroke-width="8"/> | ||||
|   </svg> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 3.0 KiB | 
							
								
								
									
										
											BIN
										
									
								
								docz/static/img/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						| After Width: | Height: | Size: 64 KiB | 
							
								
								
									
										534
									
								
								docz/static/img/formats.svg
									
									
									
									
									
										Normal file
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,534 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" | ||||
|  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> | ||||
| <!-- Generated by graphviz version 3.0.0 (20220226.1711) | ||||
|  --> | ||||
| <!-- Title: G Pages: 1 --> | ||||
| <svg width="836pt" height="816pt" | ||||
|  viewBox="0.00 0.00 835.92 815.55" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | ||||
| <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 811.55)"> | ||||
| <title>G</title> | ||||
| <polygon fill="white" stroke="transparent" points="-4,4 -4,-811.55 831.92,-811.55 831.92,4 -4,4"/> | ||||
| <!-- csf --> | ||||
| <g id="node1" class="node"> | ||||
| <title>csf</title> | ||||
| <ellipse fill="none" stroke="black" cx="413.33" cy="-403.68" rx="65.54" ry="65.54"/> | ||||
| <ellipse fill="none" stroke="black" cx="413.33" cy="-403.68" rx="69.52" ry="69.52"/> | ||||
| <text text-anchor="middle" x="413.33" y="-422.48" font-family="Indie Flower" font-size="14.00">Common</text> | ||||
| <text text-anchor="middle" x="413.33" y="-407.48" font-family="Indie Flower" font-size="14.00">Spreadsheet</text> | ||||
| <text text-anchor="middle" x="413.33" y="-392.48" font-family="Indie Flower" font-size="14.00">Format</text> | ||||
| <text text-anchor="middle" x="413.33" y="-377.48" font-family="Indie Flower" font-size="14.00">(JS Object)</text> | ||||
| </g> | ||||
| <!-- xls2 --> | ||||
| <g id="node2" class="node"> | ||||
| <title>xls2</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="790.45" cy="-403.68" rx="37.45" ry="26.74"/> | ||||
| <text text-anchor="middle" x="790.45" y="-407.48" font-family="Indie Flower" font-size="14.00">XLS</text> | ||||
| <text text-anchor="middle" x="790.45" y="-392.48" font-family="Indie Flower" font-size="14.00">BIFF2</text> | ||||
| </g> | ||||
| <!-- csf->xls2 --> | ||||
| <g id="edge25" class="edge"> | ||||
| <title>csf->xls2</title> | ||||
| <path fill="none" stroke="#458b74" d="M482.94,-409.06C558.69,-411.11 677.75,-410.86 743.28,-408.33"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="743.48,-411.83 753.32,-407.91 743.18,-404.83 743.48,-411.83"/> | ||||
| </g> | ||||
| <!-- xls3 --> | ||||
| <g id="node3" class="node"> | ||||
| <title>xls3</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="781.53" cy="-485.19" rx="37.45" ry="26.74"/> | ||||
| <text text-anchor="middle" x="781.53" y="-488.99" font-family="Indie Flower" font-size="14.00">XLS</text> | ||||
| <text text-anchor="middle" x="781.53" y="-473.99" font-family="Indie Flower" font-size="14.00">BIFF3</text> | ||||
| </g> | ||||
| <!-- csf->xls3 --> | ||||
| <g id="edge27" class="edge"> | ||||
| <title>csf->xls3</title> | ||||
| <path fill="none" stroke="#458b74" d="M480.13,-423.98C553.65,-442.35 669.94,-467.84 734.47,-479.53"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="733.91,-482.99 744.37,-481.29 735.14,-476.1 733.91,-482.99"/> | ||||
| </g> | ||||
| <!-- xls4 --> | ||||
| <g id="node4" class="node"> | ||||
| <title>xls4</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="755.21" cy="-562.84" rx="37.45" ry="26.74"/> | ||||
| <text text-anchor="middle" x="755.21" y="-566.64" font-family="Indie Flower" font-size="14.00">XLS</text> | ||||
| <text text-anchor="middle" x="755.21" y="-551.64" font-family="Indie Flower" font-size="14.00">BIFF4</text> | ||||
| </g> | ||||
| <!-- csf->xls4 --> | ||||
| <g id="edge29" class="edge"> | ||||
| <title>csf->xls4</title> | ||||
| <path fill="none" stroke="#458b74" d="M474.16,-437.93C542.38,-471.96 651.29,-522.38 711.56,-547.6"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="710.58,-550.98 721.16,-551.57 713.25,-544.51 710.58,-550.98"/> | ||||
| </g> | ||||
| <!-- xls5 --> | ||||
| <g id="node5" class="node"> | ||||
| <title>xls5</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="712.74" cy="-632.97" rx="37.45" ry="26.74"/> | ||||
| <text text-anchor="middle" x="712.74" y="-636.77" font-family="Indie Flower" font-size="14.00">XLS</text> | ||||
| <text text-anchor="middle" x="712.74" y="-621.77" font-family="Indie Flower" font-size="14.00">BIFF5</text> | ||||
| </g> | ||||
| <!-- csf->xls5 --> | ||||
| <g id="edge7" class="edge"> | ||||
| <title>csf->xls5</title> | ||||
| <path fill="none" stroke="blue" d="M465.32,-450.27C525.2,-498.75 622.04,-572.55 675.09,-609.83"/> | ||||
| <polygon fill="blue" stroke="blue" points="673.32,-612.87 683.53,-615.71 677.32,-607.12 673.32,-612.87"/> | ||||
| </g> | ||||
| <!-- xls8 --> | ||||
| <g id="node6" class="node"> | ||||
| <title>xls8</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="656.1" cy="-692.26" rx="37.45" ry="26.74"/> | ||||
| <text text-anchor="middle" x="656.1" y="-696.06" font-family="Indie Flower" font-size="14.00">XLS</text> | ||||
| <text text-anchor="middle" x="656.1" y="-681.06" font-family="Indie Flower" font-size="14.00">BIFF8</text> | ||||
| </g> | ||||
| <!-- csf->xls8 --> | ||||
| <g id="edge9" class="edge"> | ||||
| <title>csf->xls8</title> | ||||
| <path fill="none" stroke="blue" d="M454.03,-460.41C502.64,-521.47 582.67,-616.11 626.05,-663.39"/> | ||||
| <polygon fill="blue" stroke="blue" points="623.57,-665.87 632.94,-670.83 628.71,-661.12 623.57,-665.87"/> | ||||
| </g> | ||||
| <!-- xlml --> | ||||
| <g id="node7" class="node"> | ||||
| <title>xlml</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="579.16" cy="-742.38" rx="47.25" ry="26.74"/> | ||||
| <text text-anchor="middle" x="579.16" y="-746.18" font-family="Indie Flower" font-size="14.00">SSML</text> | ||||
| <text text-anchor="middle" x="579.16" y="-731.18" font-family="Indie Flower" font-size="14.00">(2003/4)</text> | ||||
| </g> | ||||
| <!-- csf->xlml --> | ||||
| <g id="edge5" class="edge"> | ||||
| <title>csf->xlml</title> | ||||
| <path fill="none" stroke="blue" d="M439.11,-468.56C471.78,-540.11 527.17,-652.46 557.68,-708.4"/> | ||||
| <polygon fill="blue" stroke="blue" points="554.64,-710.14 562.54,-717.2 560.77,-706.76 554.64,-710.14"/> | ||||
| </g> | ||||
| <!-- xlsx --> | ||||
| <g id="node8" class="node"> | ||||
| <title>xlsx</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="491.7" cy="-772.57" rx="38.37" ry="26.74"/> | ||||
| <text text-anchor="middle" x="491.7" y="-776.37" font-family="Indie Flower" font-size="14.00">XLSX</text> | ||||
| <text text-anchor="middle" x="491.7" y="-761.37" font-family="Indie Flower" font-size="14.00">XLSM</text> | ||||
| </g> | ||||
| <!-- csf->xlsx --> | ||||
| <g id="edge1" class="edge"> | ||||
| <title>csf->xlsx</title> | ||||
| <path fill="none" stroke="blue" d="M422.54,-472.89C436.95,-551.07 463.73,-675.33 479.65,-736.35"/> | ||||
| <polygon fill="blue" stroke="blue" points="476.34,-737.52 482.3,-746.28 483.1,-735.72 476.34,-737.52"/> | ||||
| </g> | ||||
| <!-- xlsb --> | ||||
| <g id="node9" class="node"> | ||||
| <title>xlsb</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="403.76" cy="-780.68" rx="43.27" ry="26.74"/> | ||||
| <text text-anchor="middle" x="403.76" y="-784.48" font-family="Indie Flower" font-size="14.00">XLSB</text> | ||||
| <text text-anchor="middle" x="403.76" y="-769.48" font-family="Indie Flower" font-size="14.00">BIFF12</text> | ||||
| </g> | ||||
| <!-- csf->xlsb --> | ||||
| <g id="edge3" class="edge"> | ||||
| <title>csf->xlsb</title> | ||||
| <path fill="none" stroke="blue" d="M406.19,-473.13C402,-552.92 399.14,-680.89 400.48,-743.6"/> | ||||
| <polygon fill="blue" stroke="blue" points="396.99,-743.91 400.76,-753.81 403.99,-743.72 396.99,-743.91"/> | ||||
| </g> | ||||
| <!-- nums --> | ||||
| <g id="node10" class="node"> | ||||
| <title>nums</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="299.96" cy="-763.36" rx="55.49" ry="18"/> | ||||
| <text text-anchor="middle" x="299.96" y="-759.66" font-family="Indie Flower" font-size="14.00">NUMBERS</text> | ||||
| </g> | ||||
| <!-- csf->nums --> | ||||
| <g id="edge23" class="edge"> | ||||
| <title>csf->nums</title> | ||||
| <path fill="none" stroke="blue" d="M387.28,-468.45C359.87,-547.84 319.17,-678.77 304.78,-735.61"/> | ||||
| <polygon fill="blue" stroke="blue" points="301.37,-734.79 302.4,-745.33 308.18,-736.45 301.37,-734.79"/> | ||||
| </g> | ||||
| <!-- ods --> | ||||
| <g id="node11" class="node"> | ||||
| <title>ods</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="215.6" cy="-724.8" rx="30.59" ry="18"/> | ||||
| <text text-anchor="middle" x="215.6" y="-721.1" font-family="Indie Flower" font-size="14.00">ODS</text> | ||||
| </g> | ||||
| <!-- csf->ods --> | ||||
| <g id="edge13" class="edge"> | ||||
| <title>csf->ods</title> | ||||
| <path fill="none" stroke="blue" d="M372.25,-460.14C326.52,-530.09 255.55,-646.35 227.44,-698.33"/> | ||||
| <polygon fill="blue" stroke="blue" points="224.3,-696.79 222.7,-707.26 230.48,-700.07 224.3,-696.79"/> | ||||
| </g> | ||||
| <!-- fods --> | ||||
| <g id="node12" class="node"> | ||||
| <title>fods</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="157.15" cy="-680.43" rx="36" ry="18"/> | ||||
| <text text-anchor="middle" x="157.15" y="-676.73" font-family="Indie Flower" font-size="14.00">FODS</text> | ||||
| </g> | ||||
| <!-- csf->fods --> | ||||
| <g id="edge15" class="edge"> | ||||
| <title>csf->fods</title> | ||||
| <path fill="none" stroke="blue" d="M362.1,-451.11C304.39,-510.17 213.75,-608.81 175.28,-655.09"/> | ||||
| <polygon fill="blue" stroke="blue" points="172.34,-653.15 168.72,-663.1 177.76,-657.58 172.34,-653.15"/> | ||||
| </g> | ||||
| <!-- html --> | ||||
| <g id="node14" class="node"> | ||||
| <title>html</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="103.98" cy="-619.37" rx="38.37" ry="26.74"/> | ||||
| <text text-anchor="middle" x="103.98" y="-623.17" font-family="Indie Flower" font-size="14.00">HTML</text> | ||||
| <text text-anchor="middle" x="103.98" y="-608.17" font-family="Indie Flower" font-size="14.00">Table</text> | ||||
| </g> | ||||
| <!-- csf->html --> | ||||
| <g id="edge50" class="edge"> | ||||
| <title>csf->html</title> | ||||
| <path fill="none" stroke="#458b74" d="M353.15,-439.08C288.12,-481.86 186.98,-552.76 135.84,-591.74"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="133.57,-589.07 127.78,-597.94 137.84,-594.62 133.57,-589.07"/> | ||||
| </g> | ||||
| <!-- csv --> | ||||
| <g id="node15" class="node"> | ||||
| <title>csv</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="67.87" cy="-554.93" rx="28.7" ry="18"/> | ||||
| <text text-anchor="middle" x="67.87" y="-551.23" font-family="Indie Flower" font-size="14.00">CSV</text> | ||||
| </g> | ||||
| <!-- csf->csv --> | ||||
| <g id="edge44" class="edge"> | ||||
| <title>csf->csv</title> | ||||
| <path fill="none" stroke="#458b74" d="M347.41,-426.68C272.23,-457.2 152.63,-510.03 97.48,-537.51"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="95.61,-534.54 88.27,-542.18 98.77,-540.79 95.61,-534.54"/> | ||||
| </g> | ||||
| <!-- txt --> | ||||
| <g id="node16" class="node"> | ||||
| <title>txt</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="43.84" cy="-479.16" rx="43.68" ry="26.74"/> | ||||
| <text text-anchor="middle" x="43.84" y="-482.96" font-family="Indie Flower" font-size="14.00">TXT</text> | ||||
| <text text-anchor="middle" x="43.84" y="-467.96" font-family="Indie Flower" font-size="14.00">UTF-16</text> | ||||
| </g> | ||||
| <!-- csf->txt --> | ||||
| <g id="edge46" class="edge"> | ||||
| <title>csf->txt</title> | ||||
| <path fill="none" stroke="#458b74" d="M344.05,-412.35C270.81,-425.26 157.16,-448.67 92.75,-464.28"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="91.72,-460.93 82.84,-466.72 93.39,-467.73 91.72,-460.93"/> | ||||
| </g> | ||||
| <!-- dbf --> | ||||
| <g id="node17" class="node"> | ||||
| <title>dbf</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="36.23" cy="-400.04" rx="28.7" ry="18"/> | ||||
| <text text-anchor="middle" x="36.23" y="-396.34" font-family="Indie Flower" font-size="14.00">DBF</text> | ||||
| </g> | ||||
| <!-- csf->dbf --> | ||||
| <g id="edge48" class="edge"> | ||||
| <title>csf->dbf</title> | ||||
| <path fill="none" stroke="#458b74" d="M343.77,-397.63C264.53,-394.72 137.86,-393.86 74.68,-396.12"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="74.22,-392.64 64.37,-396.55 74.51,-399.63 74.22,-392.64"/> | ||||
| </g> | ||||
| <!-- dif --> | ||||
| <g id="node18" class="node"> | ||||
| <title>dif</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="42.05" cy="-337.58" rx="27" ry="18"/> | ||||
| <text text-anchor="middle" x="42.05" y="-333.88" font-family="Indie Flower" font-size="14.00">DIF</text> | ||||
| </g> | ||||
| <!-- csf->dif --> | ||||
| <g id="edge32" class="edge"> | ||||
| <title>csf->dif</title> | ||||
| <path fill="none" stroke="#458b74" d="M345.74,-386.19C267.48,-370.06 141.4,-348.01 79.2,-339.91"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="79.42,-336.41 69.06,-338.65 78.55,-343.36 79.42,-336.41"/> | ||||
| </g> | ||||
| <!-- slk --> | ||||
| <g id="node19" class="node"> | ||||
| <title>slk</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="59.69" cy="-272.68" rx="33.29" ry="18"/> | ||||
| <text text-anchor="middle" x="59.69" y="-268.98" font-family="Indie Flower" font-size="14.00">SYLK</text> | ||||
| </g> | ||||
| <!-- csf->slk --> | ||||
| <g id="edge30" class="edge"> | ||||
| <title>csf->slk</title> | ||||
| <path fill="none" stroke="#458b74" d="M349.92,-374.46C277.49,-345.38 161.16,-302.63 100.09,-282.93"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="101.01,-279.55 90.42,-279.87 98.89,-286.23 101.01,-279.55"/> | ||||
| </g> | ||||
| <!-- prn --> | ||||
| <g id="node20" class="node"> | ||||
| <title>prn</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="89.74" cy="-210.01" rx="29.5" ry="18"/> | ||||
| <text text-anchor="middle" x="89.74" y="-206.31" font-family="Indie Flower" font-size="14.00">PRN</text> | ||||
| </g> | ||||
| <!-- csf->prn --> | ||||
| <g id="edge42" class="edge"> | ||||
| <title>csf->prn</title> | ||||
| <path fill="none" stroke="#458b74" d="M356.36,-363.32C288.77,-320.34 178.35,-254.72 123.22,-225.16"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="124.7,-221.99 114.22,-220.41 121.43,-228.18 124.7,-221.99"/> | ||||
| </g> | ||||
| <!-- rtf --> | ||||
| <g id="node21" class="node"> | ||||
| <title>rtf</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="127.35" cy="-157.84" rx="27.9" ry="18"/> | ||||
| <text text-anchor="middle" x="127.35" y="-154.14" font-family="Indie Flower" font-size="14.00">RTF</text> | ||||
| </g> | ||||
| <!-- csf->rtf --> | ||||
| <g id="edge40" class="edge"> | ||||
| <title>csf->rtf</title> | ||||
| <path fill="none" stroke="#458b74" d="M360.21,-358.02C298.04,-304.57 197.75,-218.36 151.79,-178.85"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="153.98,-176.12 144.12,-172.25 149.42,-181.43 153.98,-176.12"/> | ||||
| </g> | ||||
| <!-- wk1 --> | ||||
| <g id="node22" class="node"> | ||||
| <title>wk1</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="174.29" cy="-112" rx="30.59" ry="18"/> | ||||
| <text text-anchor="middle" x="174.29" y="-108.3" font-family="Indie Flower" font-size="14.00">WK1</text> | ||||
| </g> | ||||
| <!-- csf->wk1 --> | ||||
| <g id="edge34" class="edge"> | ||||
| <title>csf->wk1</title> | ||||
| <path fill="none" stroke="#458b74" d="M373.36,-346.44C323.28,-281.83 239.2,-179.96 198.15,-134.79"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="200.59,-132.27 191.24,-127.28 195.44,-137.01 200.59,-132.27"/> | ||||
| </g> | ||||
| <!-- wk3 --> | ||||
| <g id="node24" class="node"> | ||||
| <title>wk3</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="230.73" cy="-73.72" rx="30.59" ry="18"/> | ||||
| <text text-anchor="middle" x="230.73" y="-70.02" font-family="Indie Flower" font-size="14.00">WK3</text> | ||||
| </g> | ||||
| <!-- csf->wk3 --> | ||||
| <g id="edge18" class="edge"> | ||||
| <title>csf->wk3</title> | ||||
| <path fill="none" stroke="blue" d="M384.33,-340.17C346.31,-266.87 281.03,-149.9 249.12,-98.87"/> | ||||
| <polygon fill="blue" stroke="blue" points="251.89,-96.69 243.57,-90.13 245.98,-100.45 251.89,-96.69"/> | ||||
| </g> | ||||
| <!-- eth --> | ||||
| <g id="node32" class="node"> | ||||
| <title>eth</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="291.3" cy="-46.85" rx="28.7" ry="18"/> | ||||
| <text text-anchor="middle" x="291.3" y="-43.15" font-family="Indie Flower" font-size="14.00">ETH</text> | ||||
| </g> | ||||
| <!-- csf->eth --> | ||||
| <g id="edge51" class="edge"> | ||||
| <title>csf->eth</title> | ||||
| <path fill="none" stroke="#458b74" d="M395.89,-336.08C371.11,-256.68 326.85,-128.82 304.52,-73.62"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="307.67,-72.09 300.62,-64.19 301.21,-74.77 307.67,-72.09"/> | ||||
| </g> | ||||
| <!-- xls2->csf --> | ||||
| <g id="edge24" class="edge"> | ||||
| <title>xls2->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M753.25,-399.45C693.11,-396.65 573.17,-396.18 493.07,-398.05"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="492.92,-394.55 483.01,-398.3 493.1,-401.55 492.92,-394.55"/> | ||||
| </g> | ||||
| <!-- xls3->csf --> | ||||
| <g id="edge26" class="edge"> | ||||
| <title>xls3->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M747.79,-473.47C690.3,-457.8 571.89,-431.09 492.53,-415.44"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="493.05,-411.98 482.57,-413.5 491.71,-418.85 493.05,-411.98"/> | ||||
| </g> | ||||
| <!-- xls4->csf --> | ||||
| <g id="edge28" class="edge"> | ||||
| <title>xls4->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M726.87,-545.2C675,-517.77 563.3,-465.18 488.2,-432.32"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="489.34,-429 478.77,-428.22 486.55,-435.42 489.34,-429"/> | ||||
| </g> | ||||
| <!-- xls5->csf --> | ||||
| <g id="edge8" class="edge"> | ||||
| <title>xls5->csf</title> | ||||
| <path fill="none" stroke="blue" d="M690.61,-611.1C646.74,-573.63 547.39,-496.82 480.31,-447.87"/> | ||||
| <polygon fill="blue" stroke="blue" points="482.03,-444.8 471.88,-441.75 477.91,-450.46 482.03,-444.8"/> | ||||
| </g> | ||||
| <!-- xls8->csf --> | ||||
| <g id="edge10" class="edge"> | ||||
| <title>xls8->csf</title> | ||||
| <path fill="none" stroke="blue" d="M640.37,-667.64C606.25,-622.16 524.54,-524.1 469.01,-461.12"/> | ||||
| <polygon fill="blue" stroke="blue" points="471.62,-458.79 462.37,-453.62 466.38,-463.43 471.62,-458.79"/> | ||||
| </g> | ||||
| <!-- xlml->csf --> | ||||
| <g id="edge6" class="edge"> | ||||
| <title>xlml->csf</title> | ||||
| <path fill="none" stroke="blue" d="M570.33,-715.83C548.54,-663.98 492.39,-547.88 453.44,-472.8"/> | ||||
| <polygon fill="blue" stroke="blue" points="456.5,-471.11 448.78,-463.86 450.3,-474.34 456.5,-471.11"/> | ||||
| </g> | ||||
| <!-- xlsx->csf --> | ||||
| <g id="edge2" class="edge"> | ||||
| <title>xlsx->csf</title> | ||||
| <path fill="none" stroke="blue" d="M489.73,-745.57C481.38,-690.48 455.03,-563.36 435.43,-480.6"/> | ||||
| <polygon fill="blue" stroke="blue" points="438.8,-479.65 433.07,-470.74 431.99,-481.28 438.8,-479.65"/> | ||||
| </g> | ||||
| <!-- xlsb->csf --> | ||||
| <g id="edge4" class="edge"> | ||||
| <title>xlsb->csf</title> | ||||
| <path fill="none" stroke="blue" d="M408.15,-753.66C412.83,-697.93 416.76,-568.36 416.93,-483.47"/> | ||||
| <polygon fill="blue" stroke="blue" points="420.43,-483.35 416.94,-473.35 413.43,-483.35 420.43,-483.35"/> | ||||
| </g> | ||||
| <!-- nums->csf --> | ||||
| <g id="edge22" class="edge"> | ||||
| <title>nums->csf</title> | ||||
| <path fill="none" stroke="blue" d="M308.97,-745.49C327.76,-698.09 369.92,-567 394.67,-481.62"/> | ||||
| <polygon fill="blue" stroke="blue" points="398.05,-482.54 397.45,-471.96 391.32,-480.61 398.05,-482.54"/> | ||||
| </g> | ||||
| <!-- ods->csf --> | ||||
| <g id="edge12" class="edge"> | ||||
| <title>ods->csf</title> | ||||
| <path fill="none" stroke="blue" d="M229.64,-708.37C259.96,-665.94 331.65,-550.97 376.04,-475.01"/> | ||||
| <polygon fill="blue" stroke="blue" points="379.31,-476.35 381.31,-465.95 373.25,-472.83 379.31,-476.35"/> | ||||
| </g> | ||||
| <!-- fods->csf --> | ||||
| <g id="edge14" class="edge"> | ||||
| <title>fods->csf</title> | ||||
| <path fill="none" stroke="blue" d="M176.15,-665.09C215.32,-627.8 305.77,-531.13 363,-466.36"/> | ||||
| <polygon fill="blue" stroke="blue" points="365.83,-468.44 369.81,-458.62 360.57,-463.82 365.83,-468.44"/> | ||||
| </g> | ||||
| <!-- uos --> | ||||
| <g id="node13" class="node"> | ||||
| <title>uos</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="355.64" cy="-31" rx="30.59" ry="18"/> | ||||
| <text text-anchor="middle" x="355.64" y="-27.3" font-family="Indie Flower" font-size="14.00">UOS</text> | ||||
| </g> | ||||
| <!-- uos->csf --> | ||||
| <g id="edge16" class="edge"> | ||||
| <title>uos->csf</title> | ||||
| <path fill="none" stroke="blue" d="M358.42,-48.98C366,-97.91 387.33,-235.76 401.07,-324.5"/> | ||||
| <polygon fill="blue" stroke="blue" points="397.63,-325.18 402.62,-334.53 404.55,-324.11 397.63,-325.18"/> | ||||
| </g> | ||||
| <!-- html->csf --> | ||||
| <g id="edge49" class="edge"> | ||||
| <title>html->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M134.59,-603.02C184.75,-571.6 285.28,-502.14 350.91,-454.07"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="353.15,-456.77 359.14,-448.02 349.01,-451.13 353.15,-456.77"/> | ||||
| </g> | ||||
| <!-- csv->csf --> | ||||
| <g id="edge43" class="edge"> | ||||
| <title>csv->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M94.2,-547.45C146.65,-528.05 265.66,-476.64 342.6,-440.79"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="344.2,-443.91 351.77,-436.5 341.23,-437.57 344.2,-443.91"/> | ||||
| </g> | ||||
| <!-- txt->csf --> | ||||
| <g id="edge45" class="edge"> | ||||
| <title>txt->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M87.49,-474.85C148.63,-464.96 260.72,-442.44 336.13,-425.2"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="337.1,-428.57 346.05,-422.92 335.52,-421.75 337.1,-428.57"/> | ||||
| </g> | ||||
| <!-- dbf->csf --> | ||||
| <g id="edge47" class="edge"> | ||||
| <title>dbf->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M64.23,-404.06C120.46,-407.82 248.93,-409.69 333.36,-408.54"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="333.48,-412.04 343.43,-408.39 333.37,-405.04 333.48,-412.04"/> | ||||
| </g> | ||||
| <!-- dif->csf --> | ||||
| <g id="edge39" class="edge"> | ||||
| <title>dif->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M66.36,-345.56C119.67,-358.46 248.86,-382.15 333.67,-395.22"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="333.37,-398.72 343.78,-396.76 334.43,-391.8 333.37,-398.72"/> | ||||
| </g> | ||||
| <!-- slk->csf --> | ||||
| <g id="edge31" class="edge"> | ||||
| <title>slk->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M83.29,-285.33C134.11,-307.67 255.79,-353.44 336.35,-381.18"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="335.37,-384.54 345.96,-384.47 337.64,-377.92 335.37,-384.54"/> | ||||
| </g> | ||||
| <!-- prn->csf --> | ||||
| <g id="edge41" class="edge"> | ||||
| <title>prn->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M107.26,-224.48C150.82,-254.64 265.79,-324.31 341.77,-367.42"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="340.4,-370.67 350.83,-372.54 343.85,-364.58 340.4,-370.67"/> | ||||
| </g> | ||||
| <!-- wk1->csf --> | ||||
| <g id="edge33" class="edge"> | ||||
| <title>wk1->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M184.31,-129.31C213.71,-170.98 300.37,-277.99 358.3,-345.42"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="355.68,-347.74 364.86,-353.03 360.98,-343.17 355.68,-347.74"/> | ||||
| </g> | ||||
| <!-- wksl --> | ||||
| <g id="node23" class="node"> | ||||
| <title>wksl</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="428.51" cy="-26.87" rx="35.21" ry="26.74"/> | ||||
| <text text-anchor="middle" x="428.51" y="-30.67" font-family="Indie Flower" font-size="14.00">WKS</text> | ||||
| <text text-anchor="middle" x="428.51" y="-15.67" font-family="Indie Flower" font-size="14.00">Lotus</text> | ||||
| </g> | ||||
| <!-- wksl->csf --> | ||||
| <g id="edge37" class="edge"> | ||||
| <title>wksl->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M427.42,-53.97C425.17,-109.67 419.97,-238.9 416.55,-323.7"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="413.05,-323.68 416.14,-333.82 420.04,-323.97 413.05,-323.68"/> | ||||
| </g> | ||||
| <!-- wk3->csf --> | ||||
| <g id="edge17" class="edge"> | ||||
| <title>wk3->csf</title> | ||||
| <path fill="none" stroke="blue" d="M237.03,-91.6C257.98,-137.18 324.61,-259.29 369.76,-336.57"/> | ||||
| <polygon fill="blue" stroke="blue" points="366.8,-338.45 374.88,-345.3 372.83,-334.91 366.8,-338.45"/> | ||||
| </g> | ||||
| <!-- wk4 --> | ||||
| <g id="node25" class="node"> | ||||
| <title>wk4</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="500.81" cy="-36.85" rx="30.59" ry="18"/> | ||||
| <text text-anchor="middle" x="500.81" y="-33.15" font-family="Indie Flower" font-size="14.00">WK4</text> | ||||
| </g> | ||||
| <!-- wk4->csf --> | ||||
| <g id="edge19" class="edge"> | ||||
| <title>wk4->csf</title> | ||||
| <path fill="none" stroke="blue" d="M496.53,-54.79C484.99,-103.2 452.67,-238.7 431.88,-325.89"/> | ||||
| <polygon fill="blue" stroke="blue" points="428.44,-325.21 429.53,-335.75 435.25,-326.83 428.44,-325.21"/> | ||||
| </g> | ||||
| <!-- 123 --> | ||||
| <g id="node26" class="node"> | ||||
| <title>123</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="562.2" cy="-57.19" rx="27" ry="18"/> | ||||
| <text text-anchor="middle" x="562.2" y="-53.49" font-family="Indie Flower" font-size="14.00">123</text> | ||||
| </g> | ||||
| <!-- 123->csf --> | ||||
| <g id="edge20" class="edge"> | ||||
| <title>123->csf</title> | ||||
| <path fill="none" stroke="blue" d="M554.61,-74.85C534.7,-121.19 480.06,-248.36 444.86,-330.29"/> | ||||
| <polygon fill="blue" stroke="blue" points="441.61,-328.98 440.88,-339.55 448.04,-331.75 441.61,-328.98"/> | ||||
| </g> | ||||
| <!-- wksm --> | ||||
| <g id="node27" class="node"> | ||||
| <title>wksm</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="626.15" cy="-92.35" rx="38.78" ry="26.74"/> | ||||
| <text text-anchor="middle" x="626.15" y="-96.15" font-family="Indie Flower" font-size="14.00">WKS</text> | ||||
| <text text-anchor="middle" x="626.15" y="-81.15" font-family="Indie Flower" font-size="14.00">Works</text> | ||||
| </g> | ||||
| <!-- wksm->csf --> | ||||
| <g id="edge38" class="edge"> | ||||
| <title>wksm->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M609.45,-116.78C577.31,-163.8 505.87,-268.3 458.67,-337.35"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="455.5,-335.78 452.75,-346.01 461.28,-339.73 455.5,-335.78"/> | ||||
| </g> | ||||
| <!-- xlr --> | ||||
| <g id="node28" class="node"> | ||||
| <title>xlr</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="682.79" cy="-139.85" rx="27.9" ry="18"/> | ||||
| <text text-anchor="middle" x="682.79" y="-136.15" font-family="Indie Flower" font-size="14.00">XLR</text> | ||||
| </g> | ||||
| <!-- xlr->csf --> | ||||
| <g id="edge35" class="edge"> | ||||
| <title>xlr->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M667.14,-155.17C629.68,-191.84 533.36,-286.15 470.74,-347.47"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="467.97,-345.28 463.27,-354.78 472.87,-350.28 467.97,-345.28"/> | ||||
| </g> | ||||
| <!-- wq1 --> | ||||
| <g id="node29" class="node"> | ||||
| <title>wq1</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="725.17" cy="-191.62" rx="31.7" ry="18"/> | ||||
| <text text-anchor="middle" x="725.17" y="-187.92" font-family="Indie Flower" font-size="14.00">WQ1</text> | ||||
| </g> | ||||
| <!-- wq1->csf --> | ||||
| <g id="edge36" class="edge"> | ||||
| <title>wq1->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M704.71,-205.53C659.79,-236.08 550.87,-310.15 479.67,-358.56"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="477.48,-355.82 471.18,-364.34 481.42,-361.61 477.48,-355.82"/> | ||||
| </g> | ||||
| <!-- wq2 --> | ||||
| <g id="node30" class="node"> | ||||
| <title>wq2</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="760.41" cy="-256.21" rx="34.8" ry="26.74"/> | ||||
| <text text-anchor="middle" x="760.41" y="-260.01" font-family="Indie Flower" font-size="14.00">WQ2</text> | ||||
| <text text-anchor="middle" x="760.41" y="-245.01" font-family="Indie Flower" font-size="14.00">WB*</text> | ||||
| </g> | ||||
| <!-- wq2->csf --> | ||||
| <g id="edge11" class="edge"> | ||||
| <title>wq2->csf</title> | ||||
| <path fill="none" stroke="blue" d="M729.92,-269.16C676.06,-292.05 562.68,-340.22 487.26,-372.27"/> | ||||
| <polygon fill="blue" stroke="blue" points="485.63,-369.16 477.8,-376.29 488.37,-375.6 485.63,-369.16"/> | ||||
| </g> | ||||
| <!-- qpw --> | ||||
| <g id="node31" class="node"> | ||||
| <title>qpw</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="782.58" cy="-327.05" rx="32.49" ry="18"/> | ||||
| <text text-anchor="middle" x="782.58" y="-323.35" font-family="Indie Flower" font-size="14.00">QPW</text> | ||||
| </g> | ||||
| <!-- qpw->csf --> | ||||
| <g id="edge21" class="edge"> | ||||
| <title>qpw->csf</title> | ||||
| <path fill="none" stroke="blue" d="M752.05,-333.38C695.54,-345.11 573.04,-370.53 491.9,-387.38"/> | ||||
| <polygon fill="blue" stroke="blue" points="490.8,-384.03 481.72,-389.49 492.22,-390.88 490.8,-384.03"/> | ||||
| </g> | ||||
| <!-- eth->csf --> | ||||
| <g id="edge52" class="edge"> | ||||
| <title>eth->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M294.25,-65.07C306.72,-113.21 351.17,-245.78 382.2,-330.05"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="378.97,-331.41 385.72,-339.57 385.53,-328.98 378.97,-331.41"/> | ||||
| </g> | ||||
| </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 26 KiB | 
							
								
								
									
										26
									
								
								docz/static/img/logo.svg
									
									
									
									
									
										Normal file
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +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" /> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 1.6 KiB | 
							
								
								
									
										35
									
								
								docz/static/img/places.svg
									
									
									
									
									
										Normal file
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,35 @@ | ||||
| <svg width="100%" height="100%" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"> | ||||
|   <polygon fill="#ffffff" points="0,0 0,1024 1024,1024 1024,0"/> | ||||
|   <g> | ||||
|     <path d="M128,320h768v192l-192,192h-384l-192,-192z" fill="transparent" stroke="#000000" stroke-width="8" /> | ||||
|     <rect x="256" y="64" width="64" height="256" fill="transparent" stroke="#000000" stroke-width="8" rx="8"/> | ||||
|     <rect x="704" y="64" width="64" height="256" fill="transparent" stroke="#000000" stroke-width="8" rx="8"/> | ||||
|     <rect x="448" y="704" width="128" height="256" fill="transparent" stroke="#000000" stroke-width="8"/> | ||||
|   </g> | ||||
|   <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" x="384" y="384" width="256" height="256"> | ||||
|     <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> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 2.4 KiB | 
							
								
								
									
										36
									
								
								docz/static/img/tools.svg
									
									
									
									
									
										Normal file
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,36 @@ | ||||
| <svg width="100%" height="100%" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"> | ||||
|   <polygon fill="#ffffff" points="0,0 0,1024 1024,1024 1024,0"/> | ||||
|   <g> | ||||
|     <rect x="320" y="128" width="384" height="136" fill="#ffffff" stroke="#000000" stroke-width="8" rx="16"/> | ||||
|     <rect x="384" y="192" width="256" height="64" fill="#ffffff" stroke="#000000" stroke-width="8" rx="16"/> | ||||
|     <rect x="128" y="256" width="768" height="192" fill="#ffffff" stroke="#000000" stroke-width="8"/> | ||||
|     <rect x="128" y="448" width="768" height="448" fill="#ffffff" stroke="#000000" stroke-width="8"/> | ||||
|     <rect x="384" y="384" width="256" height="256" fill="#ffffff" stroke="#000000" stroke-width="8"/> | ||||
|   </g> | ||||
|   <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" x="416" y="416" width="192" height="192"> | ||||
|     <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> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 2.5 KiB | 
							
								
								
									
										2
									
								
								docz/version.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,2 @@ | ||||
| const current = "0.18.7"; | ||||
| export default current; | ||||