forked from sheetjs/docs.sheetjs.com
		
	nits
This commit is contained in:
		
							parent
							
								
									86d7a8f06a
								
							
						
					
					
						commit
						aa7cc47197
					
				| @ -26,7 +26,7 @@ The ["Live Demo"](#live-demo) section includes a working demo in this page! | ||||
| ["Run the Demo Locally"](#run-the-demo-locally) shows how to run the workflow in | ||||
| iOS / Android apps, desktop apps, NodeJS scripts and other environments. | ||||
| 
 | ||||
| The follow sequence diagram shows the process: | ||||
| The following sequence diagram shows the process: | ||||
| 
 | ||||
| ```mermaid | ||||
| sequenceDiagram | ||||
| @ -934,7 +934,7 @@ Save the following to `package.json`: | ||||
|   "version": "0.0.0", | ||||
|   "main": "SheetJSNW.html", | ||||
|   "dependencies": { | ||||
|     "nw": "~0.66.0", | ||||
|     "nw": "0.77.0", | ||||
|     "xlsx": "https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz" | ||||
|   } | ||||
| }`} | ||||
|  | ||||
| @ -16,8 +16,8 @@ Web Workers and future APIs. | ||||
| ### JavaScript is a powerful language for data processing | ||||
| 
 | ||||
| The ["Common Spreadsheet Format"](/docs/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. | ||||
| representation of the core concepts of a workbook. [Utilities](/docs/api/utilities/) | ||||
| 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 [Tutorial](/docs/getting-started/example) | ||||
| @ -35,3 +35,10 @@ with the data ecosystem. | ||||
| To the greatest extent possible, data processing code should not have to worry | ||||
| about the specific file formats involved. | ||||
| 
 | ||||
| ### Data processing should be confidential | ||||
| 
 | ||||
| All SheetJS-related methods run locally. No data is sent to a third party in | ||||
| processing data. No telemetry is collected. | ||||
| 
 | ||||
| SheetJS libraries are regularly used in offline scenarios to process personally | ||||
| identifiable information (PII) and other classified data. | ||||
|  | ||||
| @ -8,11 +8,19 @@ import DocCardList from '@theme/DocCardList'; | ||||
| import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; | ||||
| 
 | ||||
| SheetJS libraries are commonly used in data pipelines for processing personally | ||||
| identifiable information (PII).  The libraries never attempt to perform network | ||||
| requests and never collect telemetry. | ||||
| identifiable information (PII). | ||||
| 
 | ||||
| **Libraries never attempt to make network requests and never collect telemetry.** | ||||
| 
 | ||||
| In practice, there are many interesting networking use cases including server | ||||
| processing of user-submitted files and fetching files from an external source. | ||||
| 
 | ||||
| When processing data from an external source, a platform-specific operation will | ||||
| obtain binary data and SheetJS libraries will process the data. | ||||
| 
 | ||||
| When exporting data, SheetJS libraries will generate raw data and | ||||
| platform-specific operations will distribute the data. | ||||
| 
 | ||||
| The demos in this section cover common use cases: | ||||
| 
 | ||||
| <ul>{useCurrentSidebarCategory().items.map((item, index) => { | ||||
|  | ||||
| @ -1,21 +1,36 @@ | ||||
| --- | ||||
| title: Lume | ||||
| sidebar_label: Lume | ||||
| description: Make static websites from spreadsheets using Lume. Seamlessly integrate data into your website using SheetJS. Illuminate data without leaving the comfort of Excel. | ||||
| pagination_prev: demos/net/index | ||||
| pagination_next: demos/mobile/index | ||||
| sidebar_custom_props: | ||||
|   type: native | ||||
| --- | ||||
| 
 | ||||
| Lume is a lightweight, fast and flexible static site generator. | ||||
| # Illuminating Data with Lume | ||||
| 
 | ||||
| The official [Sheets plugin](https://lume.land/plugins/sheets/) uses SheetJS to | ||||
| load data from spreadsheets.  New users should consult the official docs. | ||||
| [Lume](https://lume.land/) is a lightweight unopinionated static site generator. | ||||
| It has a rich ecosystem of JavaScript-powered plugins[^1] | ||||
| 
 | ||||
| [SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing | ||||
| data from spreadsheets. | ||||
| 
 | ||||
| This demo uses Lume and SheetJS (through the official "Sheets" plugin) to pull | ||||
| data from a spreadsheet and display the content in an HTML table. | ||||
| 
 | ||||
| The ["Complete Example"](#complete-example) section includes a complete website | ||||
| powered by an XLSX spreadsheet. | ||||
| 
 | ||||
| ## Integration Details | ||||
| 
 | ||||
| The official "Sheets" plugin[^2] uses SheetJS to load data from spreadsheets. | ||||
| Under the hood, the plugin uses the SheetJS `read`[^3] method to parse files and | ||||
| the `sheet_to_json`[^4] method to generate arrays of objects. | ||||
| 
 | ||||
| Lume supports refreshing data during development. The generated static sites | ||||
| include the raw data without referencing the underlying spreadsheet files. | ||||
| 
 | ||||
| ## Integration Details | ||||
| 
 | ||||
| ### Installation | ||||
| 
 | ||||
| The `sheets` plugin can be imported and invoked in `_config.ts`: | ||||
| @ -33,19 +48,19 @@ site.use(sheets()); | ||||
| export default site; | ||||
| ``` | ||||
| 
 | ||||
| ### Usage | ||||
| :::info pass | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| The official documentation includes notes for more advanced use cases. | ||||
| The lines are automatically added if `sheets` plugin is enabled during setup. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ### Usage | ||||
| 
 | ||||
| Spreadsheet files added in the `_data` subdirectory are accessible from template | ||||
| files using the name stem. | ||||
| 
 | ||||
| For example, [`pres.numbers`](https://sheetjs.com/pres.numbers) can be accessed | ||||
| using the variable `pres` in a template. | ||||
| For example, [`pres.xlsx`](https://sheetjs.com/pres.xlsx) can be accessed using | ||||
| the variable `pres` in a template. | ||||
| 
 | ||||
| #### Single-Sheet Workbooks | ||||
| 
 | ||||
| @ -81,9 +96,9 @@ _Reading all Worksheets_ | ||||
| The default behavior, when workbooks have multiple sheets, is to present objects | ||||
| whose keys are worksheet names and whose values are arrays of row objects. | ||||
| 
 | ||||
| For example, if `pres.numbers` had a sheet named `"Presidents"` and another | ||||
| sheet named `"VicePresidents"`, then the following snippet would print data | ||||
| from the `"Presidents"` sheet: | ||||
| For example, if `pres.xlsx` had a sheet named `"Presidents"` and another sheet | ||||
| named `"VicePresidents"`, then the following snippet would print data from the | ||||
| `"Presidents"` sheet: | ||||
| 
 | ||||
| ```liquid title="multi.njk" | ||||
| <table><thead><th>Name</th><th>Index</th></thead> | ||||
| @ -98,18 +113,35 @@ from the `"Presidents"` sheet: | ||||
| </table> | ||||
| ``` | ||||
| 
 | ||||
| #### File Formats | ||||
| 
 | ||||
| As explained in the official plugin documentation[^5], the loader loads XLSX. | ||||
| NUMBERS, and CSV files. Other extensions can be added through the `extensions` | ||||
| property in the argument to the `sheets` plugin: | ||||
| 
 | ||||
| ```ts | ||||
| site.use(sheets({ | ||||
|   // highlight-next-line | ||||
|   extensions: [".xlsx", ".xlsb", ".xls"] | ||||
| })); | ||||
| ``` | ||||
| 
 | ||||
| 
 | ||||
| ## Complete Example | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This was tested against `lume v1.16.2` on 2023 April 18. | ||||
| This was tested against `lume v1.17.5` on 2023 June 25. | ||||
| 
 | ||||
| This example uses the Nunjucks template format. Lume plugins support additional | ||||
| template formats, including Markdown and JSX. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ### Initial Setup | ||||
| 
 | ||||
| 0) Install Deno[^6] | ||||
| 
 | ||||
| 1) Create a stock site: | ||||
| 
 | ||||
| ```bash | ||||
| @ -126,15 +158,14 @@ When prompted, enter the following options: | ||||
| 
 | ||||
| The project will be configured and modules will be installed. | ||||
| 
 | ||||
| 2) Download <https://sheetjs.com/pres.numbers> and place in a `_data` folder: | ||||
| 2) Download <https://sheetjs.com/pres.xlsx> and place in a `_data` folder: | ||||
| 
 | ||||
| ```bash | ||||
| mkdir -p _data | ||||
| curl -L -o _data/pres.numbers https://sheetjs.com/pres.numbers | ||||
| curl -L -o _data/pres.xlsx https://sheetjs.com/pres.xlsx | ||||
| ``` | ||||
| 
 | ||||
| 3) Create a `index.njk` file that references the file.  Since the file is | ||||
|    `pres.numbers`, the parameter name is `pres`: | ||||
| 3) Create a `index.njk` file that references the file: | ||||
| 
 | ||||
| ```liquid title="index.njk" | ||||
| <h2>Presidents</h2> | ||||
| @ -150,35 +181,51 @@ curl -L -o _data/pres.numbers https://sheetjs.com/pres.numbers | ||||
| </table> | ||||
| ``` | ||||
| 
 | ||||
| Since the file name is `pres.xlsx`, the parameter name is `pres`: | ||||
| 
 | ||||
| ### Live Refresh | ||||
| 
 | ||||
| 4) Run the development server: | ||||
| 
 | ||||
| ```bash | ||||
| deno task lume --serve | ||||
| deno task serve --port 7262 | ||||
| ``` | ||||
| 
 | ||||
| To verify it works, access `http://localhost:3000` from your web browser. Open | ||||
| `_data/pres.numbers` and add a new row to the bottom of the sheet. The page will | ||||
| refresh and show the new contents. | ||||
| To verify it works, access `http://localhost:7262` from your web browser. The | ||||
| page will show the contents of the spreadsheet. | ||||
| 
 | ||||
| :::caution | ||||
| 5) While the server is still running, open `_data/pres.xlsx` in a spreadsheet | ||||
| editor and add a new row at the bottom of the sheet. | ||||
| 
 | ||||
| There is a known bug with Deno hot reloading.  If the page does not refresh | ||||
| automatically, upgrade with `deno upgrade` and restart the development server. | ||||
| The page will refresh and show the new contents. | ||||
| 
 | ||||
| ::: | ||||
| ### Static Site | ||||
| 
 | ||||
| 5) Stop the server (press `CTRL+C` in the terminal window) and run | ||||
| 6) Stop the server (press `CTRL+C` in the terminal window) and run | ||||
| 
 | ||||
| ```bash | ||||
| deno task lume | ||||
| ``` | ||||
| 
 | ||||
| This will create a static site in the `_site` folder, which can be served with: | ||||
| This will create a static site in the `_site` folder | ||||
| 
 | ||||
| 7) Test the generated site by running | ||||
| 
 | ||||
| ```bash | ||||
| npx http-server _site | ||||
| ``` | ||||
| 
 | ||||
| Accessing the page `http://localhost:8080` will show the page contents. | ||||
| The program will display a URL (typically `http://localhost:8080`). Accessing | ||||
| the page will show the contents of the spreadsheet. | ||||
| 
 | ||||
| View the page source and confirm that the page only includes an HTML table. No | ||||
| scripts are included in this page. | ||||
| 
 | ||||
| This site is self-contained and ready for deployment! | ||||
| 
 | ||||
| [^1]: See ["Plugins"](https://lume.land/plugins/?status=all) in the Lume documentation | ||||
| [^2]: See ["Sheets"](https://lume.land/plugins/sheets/) in the Lume documentation | ||||
| [^3]: See [`read` in "Reading Files"](/docs/api/parse-options) | ||||
| [^4]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output) | ||||
| [^5]: See ["Formats"](https://lume.land/plugins/sheets/#formats) in the Lume documentation | ||||
| [^6]: See ["Installation"](https://deno.com/manual/getting_started/installation) in the Deno documentation | ||||
| @ -38,15 +38,18 @@ the browser refreshes to show the new content. | ||||
| :::note Recommendation | ||||
| 
 | ||||
| It is strongly recommended to use a framework that provides an official plugin | ||||
| for working with SheetJS. Lume is a great choice for getting started. GatsbyJS | ||||
| is excellent for teams well-versed in the React JS framework. | ||||
| for working with SheetJS. | ||||
| 
 | ||||
| Lume is a great choice for lightweight sites. | ||||
| 
 | ||||
| GatsbyJS is excellent for teams well-versed in the ReactJS framework. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ### Official | ||||
| 
 | ||||
| Some frameworks provide official extensions  They are strongly recommended for | ||||
| greenfield projects.  Demos: | ||||
| Some frameworks provide official extensions. They are strongly recommended for | ||||
| greenfield projects. | ||||
| 
 | ||||
| <ul>{useCurrentSidebarCategory().items.filter(item => item.customProps?.type == "native").map(item => { | ||||
|   const listyle = (item.customProps?.icon) ? { | ||||
| @ -61,7 +64,7 @@ greenfield projects.  Demos: | ||||
| ### Bundlers | ||||
| 
 | ||||
| Bundlers can run JS code and process assets during development and during site | ||||
| builds. Custom plugins can extract data from spreadsheets.  Demos: | ||||
| builds. Custom plugins can extract data from spreadsheets. | ||||
| 
 | ||||
| <ul>{useCurrentSidebarCategory().items.filter(item => item.customProps?.type == "bundler").map(item => { | ||||
|   const listyle = (item.customProps?.icon) ? { | ||||
|  | ||||
| @ -7,9 +7,12 @@ pagination_next: demos/data/index | ||||
| import DocCardList from '@theme/DocCardList'; | ||||
| import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; | ||||
| 
 | ||||
| Web technologies like JavaScript and HTML have been adapted to the traditional | ||||
| app space.  Typically these frameworks bundle a JavaScript engine as well as a | ||||
| windowing framework. SheetJS is compatible with many app frameworks. | ||||
| Web technologies including JavaScript and HTML can power traditional software. | ||||
| 
 | ||||
| ## Desktop Apps | ||||
| 
 | ||||
| Desktop app frameworks bundle a JavaScript engine and a windowing framework to | ||||
| enable graphical apps. SheetJS is compatible with many app frameworks. | ||||
| 
 | ||||
| Demos for common desktop tools are included in separate pages: | ||||
| 
 | ||||
| @ -22,17 +25,6 @@ Demos for common desktop tools are included in separate pages: | ||||
|   </li>); | ||||
| })}</ul> | ||||
| 
 | ||||
| Demos for common command-line tools are included in separate pages: | ||||
| 
 | ||||
| <ul>{useCurrentSidebarCategory().items.filter(item => item.customProps?.cli).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> | ||||
| 
 | ||||
| :::note Desktop Recommendation | ||||
| 
 | ||||
| Electron is the most established and widely-used framework. With deep support | ||||
| @ -45,3 +37,19 @@ other programming languages. | ||||
| Frameworks like React Native generate applications that use native UI elements. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ## Command-Line Tools | ||||
| 
 | ||||
| Command-line tools bundle a JavaScript engine and a system runtime. The runtime | ||||
| provides low-level access to computer resources. | ||||
| 
 | ||||
| Demos for common command-line tools are included in separate pages: | ||||
| 
 | ||||
| <ul>{useCurrentSidebarCategory().items.filter(item => item.customProps?.cli).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> | ||||
|  | ||||
| @ -23,7 +23,7 @@ Clipboard data can be read from a `paste` event, accessible from the event | ||||
| 
 | ||||
| ```js | ||||
| document.onpaste = function(e) { | ||||
|   /* get TSV */ | ||||
|   /* get HTML */ | ||||
|   var str = e.clipboardData.getData('text/html'); | ||||
|   /* parse */ | ||||
|   var wb = XLSX.read(str, {type: "string"}); | ||||
|  | ||||
| @ -12,7 +12,7 @@ There is no standard cross-platform approach to read and write files and data. | ||||
| the file read and write operations.  Not all platforms support the APIs used in | ||||
| the library. | ||||
| 
 | ||||
| The demos in this section cover APIs that are not supported out-of-the-box: | ||||
| Demos in this section cover local APIs that are not embedded in the library: | ||||
| 
 | ||||
| <ul>{useCurrentSidebarCategory().items.map((item, index) => { | ||||
|   const listyle = (item.customProps?.icon) ? { | ||||
|  | ||||
| @ -62,6 +62,7 @@ function SheetJSChoisissez() { | ||||
|   const [msg, setMsg] = React.useState("Press the button to show a Chooser"); | ||||
|   const btn = useRef(), tbl = useRef(); | ||||
|   React.useEffect(() => { | ||||
|     if(typeof Dropbox == "undefined") return setMsg("Dropbox is not defined"); | ||||
|     /* create button */ | ||||
|     var button = Dropbox.createChooseButton({ | ||||
|       /* required settings */ | ||||
| @ -131,6 +132,7 @@ function SheetJSEnregistrez() { | ||||
|   const [msg, setMsg] = React.useState("Press the button to write XLS file"); | ||||
|   const btn = useRef(), tbl = useRef(); | ||||
|   React.useEffect(async() => { | ||||
|     if(typeof Dropbox == "undefined") return setMsg("Dropbox is not defined"); | ||||
|     /* fetch data and write table (sample data) */ | ||||
|     const f = await(await fetch("https://sheetjs.com/pres.xlsx")).arrayBuffer(); | ||||
|     const wb = XLSX.read(f); | ||||
|  | ||||
| @ -12,7 +12,7 @@ language for writing extensions for apps. Some applications like Chromium use V8 | ||||
| while others use engines that only support ES3 JavaScript. With conservative use | ||||
| of modern language features, SheetJS can be used in many app extensions. | ||||
| 
 | ||||
| Demos for common apps are included in separate pages: | ||||
| Demos for common applications are included in separate pages: | ||||
| 
 | ||||
| <ul>{useCurrentSidebarCategory().items.map((item, index) => { | ||||
|   const listyle = (item.customProps?.icon) ? { | ||||
|  | ||||
| @ -15,8 +15,10 @@ been integrated into the ReactJS framework and other foundational JS libraries. | ||||
| JS Engines have improved over the years, but there are some hard limits to | ||||
| browser support using traditional methods of data processing.  Vendors have | ||||
| introduced APIs and techniques for representing and processing very large binary | ||||
| and textual files. Since many of the techniques only work in a few engines, they | ||||
| are recommended only when the traditional approaches falter: | ||||
| and textual files. | ||||
| 
 | ||||
| Since many of the techniques only work in a few engines, they are not embedded | ||||
| in the library. They are recommended only when traditional approaches falter. | ||||
| 
 | ||||
| <ul>{useCurrentSidebarCategory().items.map((item, index) => { | ||||
|   const listyle = (item.customProps?.icon) ? { | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -146,7 +146,7 @@ This script will generate `SheetJSVBANeu.xlsm`. | ||||
| 
 | ||||
| ### Extracting VBA Blobs | ||||
| 
 | ||||
| To obtain the blob, `bookVBA: 1` must be set in the `read` or `readFile` call. | ||||
| To extract blobs, `bookVBA: true` must be set in the `read` or `readFile` call. | ||||
| 
 | ||||
| The following example extracts the embedded VBA blob in a workbook: | ||||
| 
 | ||||
|  | ||||
| @ -19,7 +19,7 @@ requirement in the user interface. For example, if the last worksheet is deleted | ||||
| in the program, Apple Numbers will automatically create a new blank sheet. | ||||
| 
 | ||||
| The SheetJS [write functions](/docs/api/write-options) enforce the requirement. | ||||
| They will throw errors when trying to export empty worksheets. | ||||
| They will throw errors when trying to export empty workbooks. | ||||
| 
 | ||||
| 
 | ||||
| **Append a Worksheet to a Workbook** | ||||
| @ -41,7 +41,7 @@ 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: | ||||
| will be chosen by finding the name stem and incrementing the counter. | ||||
| 
 | ||||
| ```js | ||||
| XLSX.utils.book_append_sheet(workbook, sheetA, "Sheet2", true); // Sheet2 | ||||
|  | ||||
| @ -282,6 +282,25 @@ import { writeFile } from 'xlsx'; // writeFile will use the global `saveAs` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| #### "Cannot save file" in NodeJS | ||||
| 
 | ||||
| The `fs` module is automatically loaded in scripts using `require`: | ||||
| 
 | ||||
| ```js | ||||
| var XLSX = require("xlsx"); // automatically loads `fs` | ||||
| ``` | ||||
| 
 | ||||
| Using the [ESM import](/docs/getting-started/installation/nodejs/#esm-import), | ||||
| the `fs` module must be imported and passed to the library: | ||||
| 
 | ||||
| ```js | ||||
| import * as XLSX from 'xlsx'; | ||||
| 
 | ||||
| /* load 'fs' for readFile and writeFile support */ | ||||
| import * as fs from 'fs'; | ||||
| XLSX.set_fs(fs); | ||||
| ``` | ||||
| 
 | ||||
| ## Data Issues | ||||
| 
 | ||||
| #### Generated XLSX files are very large! | ||||
|  | ||||
| @ -98,7 +98,7 @@ 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 | ||||
| env TZ="Asia/Kolkata" WTF=1 make test_misc | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
|  | ||||
| @ -8,6 +8,9 @@ hide_table_of_contents: true | ||||
| 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. | ||||
| 
 | ||||
| The Apache 2.0 License is a "permissive" license which allows commercial use but | ||||
| requires attribution. | ||||
| 
 | ||||
| #### Required Attribution | ||||
| 
 | ||||
| When integrating SheetJS CE in a project or service, the following text must be | ||||
|  | ||||
| @ -9,10 +9,10 @@ Some of our original research is documented at <https://oss.sheetjs.com/notes/> | ||||
| 
 | ||||
| The specifications list is non-exhaustive. | ||||
| 
 | ||||
|  - Worksheet File Format (From Lotus) December 1984 | ||||
|  - Worksheet File Format (From Lotus) December 1984[^1] | ||||
|  - Open Document Format for Office Applications Version 1.3 | ||||
| 
 | ||||
| :::info | ||||
| :::info pass | ||||
| 
 | ||||
| The primary specifications for XLSX are: | ||||
| 
 | ||||
| @ -26,9 +26,9 @@ most of the public XLSX document community use the spec names interchangeably. | ||||
| 
 | ||||
| ## 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. | ||||
| Lotus dedicated the "Worksheet File Format" documentation to 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> | ||||
| 
 | ||||
| @ -60,3 +60,7 @@ to sue.  The documentation that falls under the promise are listed below. | ||||
| 
 | ||||
| - ISBN 1556155212 "Excel Software Development Kit Version 4" | ||||
| - ISBN 1556156324 "Excel Developer's Kit Version 5" | ||||
| 
 | ||||
| [^1]: The original FTP server is no longer available, but the content has been | ||||
|       mirrored at <https://oss.sheetjs.com/notes/lotus/>. Lotus Corporation | ||||
|       dedicated the content to the public domain in 1984. | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user