diff --git a/.spelling b/.spelling index 8d944eb..e0370dd 100644 --- a/.spelling +++ b/.spelling @@ -44,7 +44,9 @@ InDesign IndexedDB JavaScriptCore LocalStorage +MacOS NestJS +NetSuite NPM Nuxt PhantomJS @@ -55,6 +57,7 @@ RequireJS Rollup SessionStorage SQLite +SuiteScripts SystemJS VueJS WebKit diff --git a/docz/docs/06-solutions/01-input.md b/docz/docs/06-solutions/01-input.md index 3f6bfd4..600f893 100644 --- a/docz/docs/06-solutions/01-input.md +++ b/docz/docs/06-solutions/01-input.md @@ -45,7 +45,9 @@ Deno scripts must be invoked with `--allow-read` to read from the filesystem. #### Examples -Here are a few common scenarios (click on each subtitle to see the code): +Here are a few common scenarios (click on each subtitle to see the code). + +The [demos](../getting-started/demos) cover special deployments in more detail. ### Example: Local File @@ -63,16 +65,14 @@ 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`: +For Node ESM, `fs` must be loaded manually: ```js -import { readFileSync } from "fs"; -import { read } from "xlsx/xlsx.mjs"; +import * as fs from "fs"; +import { readFile, set_fs } from "xlsx/xlsx.mjs"; +set_fs(fs); -const buf = readFileSync("test.xlsx"); -/* buf is a Buffer */ -const workbook = read(buf); +const workbook = readFile("test.xlsx"); ``` @@ -108,17 +108,27 @@ shows a complete example and details the required version-specific settings. +:::caution + +React Native does not provide a way to read files from the filesystem. A +separate third-party library must be used. + +Since React Native internals change between releases, libraries may only work +with specific versions of React Native. Project documentation should be +consulted before picking a library. + +:::caution + 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: +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 * as XLSX from "xlsx"; import { FileSystem } from "react-native-file-access"; const b64 = await FileSystem.readFile(path, "base64"); @@ -131,7 +141,7 @@ const workbook = XLSX.read(b64, {type: "base64"}); The `ascii` encoding returns binary strings compatible with the `binary` type: ```js -import XLSX from "xlsx"; +import * as XLSX from "xlsx"; import { readFile } from "react-native-fs"; const bstr = await readFile(path, "ascii"); @@ -293,8 +303,11 @@ The [`server` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/server) ### Example: Remote File -
- Fetching a file in the web browser ("Ajax") (click to show) +This example focuses on fetching files ("Ajax" in browser parlance) using APIs +like `XMLHttpRequest` and `fetch` as well as third-party libraries. + + + For modern websites targeting Chrome 42+, `fetch` is recommended: @@ -334,11 +347,8 @@ The [`xhr` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/xhr/) incl shows fallback approaches for IE6+. -
- - -
- Download files in a NodeJS process (click to show) + + Node 17.5 and 18.0 have native support for fetch: @@ -380,10 +390,8 @@ const axios = require("axios"); })(); ``` -
- -
- Download files in an Electron app (click to show) + + The `net` module in the main process can make HTTP/HTTPS requests to external resources. Responses should be manually concatenated using `Buffer.concat`: @@ -405,37 +413,39 @@ req.on("response", (res) => { req.end(); ``` -
+
+ ### Example: Readable Streams -
- Readable Streams in NodeJS (click to show) +:::caution -When dealing with Readable Streams, the easiest approach is to buffer the stream -and process the whole thing at the end: +The recommended approach is to buffer streams in memory and process once all of +the data has been collected. A proper streaming parse is technically impossible. -```js -var fs = require("fs"); -var XLSX = require("xlsx"); +
Technical details (click to show) -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"}); +XLSX, XLSB, NUMBERS, and ODS files are ultimately ZIP files that contain binary +and XML entries. The ZIP file format stores the table of contents ("end of +central directory" record) at the end of the file, so a proper parse of a ZIP +file requires scanning from the end. Streams do not provide random access into +the data, so the only correct approach involves buffering the entire stream. - /* DO SOMETHING WITH workbook IN THE CALLBACK */ - cb(workbook); - }); -} -``` +XLS, XLR, QPW, and Works 4 for Mac files use the "Compound File Binary Format". +It is a container format that can hold multiple "files" and "folders". It also +has a table of contents ("directory sectors") but these can be placed anywhere +in the file! The only correct approach involves buffering enough of the stream +to find the full table of contents, but the added complexity has little benefit +when testing against real-world files generated by various versions of Excel and +other tools.
-
- ReadableStream in the browser (click to show) +::: + + + + When dealing with `ReadableStream`, the easiest approach is to buffer the stream and process the whole thing at the end: @@ -470,7 +480,31 @@ const data = await process_RS(stream); const workbook = XLSX.read(data, {type: 'array'}); ``` -
+ + + +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); + }); +} +``` + + + More detailed examples are covered in the [included demos](https://github.com/SheetJS/SheetJS/tree/master/demos/) @@ -538,9 +572,9 @@ 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. - is a live demo. +[demo](https://github.com/sheetjs/sheetjs/tree/master/demos/xspreadsheet) +includes a sample script with the `xtos` function for converting from +x-spreadsheet to a workbook. Live Demo:
Records from a database query (SQL or no-SQL) (click to show) diff --git a/docz/docs/06-solutions/05-output.md b/docz/docs/06-solutions/05-output.md index 0899885..80f9d1f 100644 --- a/docz/docs/06-solutions/05-output.md +++ b/docz/docs/06-solutions/05-output.md @@ -4,9 +4,13 @@ sidebar_position: 5 # Data Export +import current from '/version.js'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + ## Writing Workbooks -#### API +### API _Generate spreadsheet bytes (file) from data_ @@ -32,9 +36,8 @@ 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. +The second `opts` argument is optional. ["Writing Options"](../api/write-options) +covers the supported properties and behaviors. _Generate and attempt to save an XLSX file_ @@ -50,71 +53,26 @@ referencing the other export functions. The second `opts` argument is optional. ["Writing Options"](../api/write-options) covers the supported properties and behaviors. +:::note + +The `writeFile` and `writeFileXLSX` methods uses platform-specific APIs to save +files. The APIs do not generally provide feedback on whether files were created. + +::: + #### Examples -
- Local file in a NodeJS server (click to show) +Here are a few common scenarios (click on each subtitle to see the code). -`writeFile` uses `fs.writeFileSync` in server environments: +The [demos](../getting-started/demos) cover special deployments in more detail. -```js -var XLSX = require("xlsx"); +### Example: Local File -/* output format determined by filename */ -XLSX.writeFile(workbook, "out.xlsb"); -``` +`XLSX.writeFile` supports writing local files in platforms like NodeJS. In other +platforms like React Native, `XLSX.write` should be called with file data. -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); -``` - -
- -
- Local file in a Deno application (click to show) - -`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 - -
- -
- Local file in a PhotoShop or InDesign plugin (click to show) - -`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. - -
- -
- Download a file in the browser to the user machine (click to show) + + `XLSX.writeFile` wraps a few techniques for triggering a file save: @@ -132,10 +90,22 @@ XLSX.writeFile(workbook, "out.xlsb"); /* at this point, out.xlsb will have been downloaded */ ``` -
-
- Download a file in legacy browsers (click to show) + SWF workaround for Windows 95+ (click to show) + +:::warning + +Each moving part in this solution has been deprecated years ago: + +- Adobe stopped supporting Flash Player at the end of 2020 +- Microsoft stopped supporting IE8 in 2019 and stopped supporting IE9 in 2020 +- `Downloadify` support ended in 2010 and `SWFObject` support ended in 2016 + +New projects should strongly consider requiring modern browsers. This info is +provided on an "as is" basis and there is no realistic way to provide support +given that every related vendor stopped providing support for their software. + +::: `XLSX.writeFile` techniques work for most modern browsers as well as older IE. For much older browsers, there are workarounds implemented by wrapper libraries. @@ -157,28 +127,123 @@ The [`oldie` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/oldie/)
-
- Browser upload file (ajax) (click to show) + + -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): +`writeFile` uses `fs.writeFileSync` under the hood: ```js -/* in this example, send a base64 string to the server */ -var wopts = { bookType:"xlsx", bookSST:false, type:"base64" }; +var XLSX = require("xlsx"); -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); +/* output format determined by filename */ +XLSX.writeFile(workbook, "out.xlsb"); ``` -
+For Node ESM, `fs` must be loaded manually: + +```js +import * as fs from "fs"; +import { writeFile, set_fs } from "xlsx/xlsx.mjs"; +set_fs(fs); + +/* output format determined by filename */ +writeFile(workbook, "out.xlsb"); +``` + + + + +`writeFile` uses `Deno.writeFileSync` under the hood: + +
{`\
+// @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';
+
+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 + +
+ + +`writeFile` can be used in the renderer process: + +```js +/* From the renderer process */ +var XLSX = require("xlsx"); + +XLSX.writeFile(workbook, "out.xlsb"); +``` + +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. + + + + +:::caution + +React Native does not provide a way to write files to the filesystem. A +separate third-party library must be used. + +Since React Native internals change between releases, libraries may only work +with specific versions of React Native. Project documentation should be +consulted before picking a library. + +::: + +The [`react` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/react) includes a sample React Native app. + +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 * as XLSX from "xlsx"; +import { Dirs, FileSystem } from "react-native-file-access"; +const DDP = Dirs.DocumentDir + "/"; + +const b64 = XLSX.write(workbook, {type:'base64', bookType:"xlsx"}); +/* b64 is a base64 string */ +await FileSystem.writeFile(DDP + "sheetjs.xlsx", b64, "base64"); +``` + +- [`react-native-fs`](https://npm.im/react-native-fs) + +The `ascii` encoding accepts binary strings compatible with the `binary` type: + +```js +import * as XLSX from "xlsx"; +import { writeFile, DocumentDirectoryPath } from "react-native-fs"; +const DDP = DocumentDirectoryPath + "/"; + +const bstr = XLSX.write(workbook, {type:'binary', bookType:"xlsx"}); +/* bstr is a binary string */ +await writeFile(DDP + "sheetjs.xlsx", bstr, "ascii"); +``` + + + + +`writeFile` wraps the `File` logic in Photoshop and other ExtendScript targets. +The specified path should be an absolute path: + +```js +#include "xlsx.extendscript.js" + +/* Ask user to select path */ +var thisFile = File.saveDialog("Select an output file", "*.xlsx;*.xls"); +/* output format determined by filename */ +XLSX.writeFile(workbook, thisFile.absoluteURI); +``` + +The [`extendscript` demo](../getting-started/demos/extendscript) includes a more complex example. + + +
PhantomJS (Headless Webkit) File Generation (click to show) @@ -203,55 +268,86 @@ to generate a workbook from HTML tables in a page in "Headless WebKit".
+
+ -The [included demos](https://github.com/SheetJS/SheetJS/tree/master/demos/) cover mobile apps and other special deployments. +### Example: Remote File -### Writing Examples +This example focuses on uploading files ("Ajax" in browser parlance) using APIs +like `XMLHttpRequest` and `fetch` as well as third-party libraries. -- exporting an HTML table -- generates a simple file + + -### Streaming Write +:::caution -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. +Some platforms like Azure and AWS will attempt to parse POST request bodies as +UTF-8 strings before user code can see the data. This will result in corrupt +data parsed by the server. There are some workarounds, but the safest approach +is to adjust the server process or Lambda function to accept Base64 strings. -- `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`. +::: -
- nodejs convert to CSV and write file (click to show) +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 -var output_file_name = "out.csv"; -var stream = XLSX.stream.to_csv(worksheet); -stream.pipe(fs.createWriteStream(output_file_name)); +/* in this example, send a base64 string to the server */ +var wbout = XLSX.write(workbook, { bookType: "xlsx", type: "base64" }); + +/* prepare data for POST */ +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 + +/* perform POST request */ +var req = new XMLHttpRequest(); +req.open("POST", "/upload", true); +req.send(formdata); ``` -
- -
- nodejs write JSON stream to screen (click to show) +For servers that do not parse POST request bodies as UTF-8 strings, a `Blob` can +be generated from the `array` output: ```js -/* to_json returns an object-mode stream */ -var stream = XLSX.stream.to_json(worksheet, {raw:true}); +/* in this example, send a Blob to the server */ +var wbout = XLSX.write(workbook, { bookType: "xlsx", type: "array" }); -/* 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"); }; +/* prepare data for POST */ +var blob = new Blob([new Uint8Array(wbout)], {type:"application/octet-stream"}); +var formdata = new FormData(); +formdata.append("file", blob, "test.xlsx"); -stream.pipe(conv); conv.pipe(process.stdout); +/* perform POST request */ +fetch("/upload", { method: 'POST', body: formdata }); ``` -
+
+ - pipes write streams to nodejs response. +`XLSX.write` with `type: "buffer"` will generate a NodeJS `Buffer` which can be +used with standard NodeJS approaches for uploading data. -### Generating JSON and JS Data +Node 17.5 and 18.0 have native support for fetch: + +```js +const XLSX = require("xlsx"); + +const buf = XLSX.write(workbook, { bookType: "xlsx", type: "buffer" }); +var blob = new Blob([buf], {type:"application/octet-stream"}); +var formdata = new FormData(); +formdata.append("file", blob, "test.xlsx"); + +/* perform POST request */ +fetch("https://thisis.a.test/upload", { method: 'POST', body: formdata }); +``` + + +
+ +## Generating JSON and JS Data JSON and JS data tend to represent single worksheets. The utility functions in this section work with single worksheets. @@ -263,7 +359,7 @@ names and whose values are worksheet objects. The "first worksheet" is stored at `workbook.Sheets[workbook.SheetNames[0]]`. -#### API +### API _Create an array of JS objects from a worksheet_ @@ -287,14 +383,19 @@ With the `header: 1` option, the function exports an array of arrays of values. #### Examples +### Example: Data Grids + + + + [`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. - is a live demo. +[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. Live Demo: -
- Previewing data in a React data grid (click to show) + + [`react-data-grid`](https://adazzle.github.io/react-data-grid) is a data grid built for React. It uses two properties: `rows` of data objects and `columns` @@ -314,7 +415,7 @@ export default function App() { const [columns, setColumns] = useState([]); const [rows, setRows] = useState([]); useEffect(() => {(async () => { - const wb = read(await (await fetch(url)).arrayBuffer(), { WTF: 1 }); + const wb = read(await (await fetch(url)).arrayBuffer()); /* 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 }); @@ -331,22 +432,23 @@ export default function App() { } ``` -
- -
- Previewing data in a VueJS data grid (click to show) + + [`vue3-table-lite`](https://linmasahiro.github.io/vue3-table-lite/dist/) is a simple VueJS 3 data table. It is featured in the [VueJS demo](https://github.com/SheetJS/SheetJS/tree/master/demos/vue/modify/). -
+
+
+ +### Example: Data Loading
Populating a database (SQL or no-SQL) (click to show) -The [`database` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/database/) includes examples of working with -databases and query results. +The [`database` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/database/) +includes examples of working with databases and query results.
@@ -390,7 +492,7 @@ The [`array` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/array/)
-### Generating HTML Tables +## Generating HTML Tables #### API @@ -416,8 +518,10 @@ container.innerHTML = XLSX.utils.sheet_to_html(worksheet); Combining with `fetch`, constructing a site from a workbook is straightforward: -
- Vanilla JS + HTML fetch workbook and generate table previews (click to show) + + + +This example assigns the `innerHTML` of a DIV element: ```html @@ -447,15 +551,15 @@ Combining with `fetch`, constructing a site from a workbook is straightforward: ``` -
- -
- React fetch workbook and generate HTML table previews (click to show) + + 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 +import * as XLSX from 'xlsx'; + function Tabeller(props) { /* the workbook object is the state */ const [workbook, setWorkbook] = React.useState(XLSX.utils.book_new()); @@ -479,10 +583,8 @@ function Tabeller(props) { The [`react` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/react) includes more React examples. -
- -
- VueJS fetch workbook and generate HTML table previews (click to show) + + 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: @@ -515,9 +617,10 @@ const S5SComponent = { The [`vuejs` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/vue) includes more React examples. -
+ + -### Generating Single-Worksheet Snapshots +## Generating Single-Worksheet Snapshots The `sheet_to_*` functions accept a worksheet object. @@ -555,3 +658,42 @@ 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. + +## 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`. + +
+ nodejs convert to CSV and write file (click to show) + +```js +var output_file_name = "out.csv"; +var stream = XLSX.stream.to_csv(worksheet); +stream.pipe(fs.createWriteStream(output_file_name)); +``` + +
+ +
+ nodejs write JSON stream to screen (click to show) + +```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); +``` + +
+ + pipes write streams to nodejs response. diff --git a/docz/docs/09-miscellany/06-testing.md b/docz/docs/09-miscellany/04-testing.md similarity index 99% rename from docz/docs/09-miscellany/06-testing.md rename to docz/docs/09-miscellany/04-testing.md index c7b3735..848c6dd 100644 --- a/docz/docs/09-miscellany/06-testing.md +++ b/docz/docs/09-miscellany/04-testing.md @@ -1,5 +1,5 @@ --- -sidebar_position: 6 +sidebar_position: 4 hide_table_of_contents: true --- diff --git a/docz/docs/09-miscellany/07-contributing.md b/docz/docs/09-miscellany/05-contributing.md similarity index 97% rename from docz/docs/09-miscellany/07-contributing.md rename to docz/docs/09-miscellany/05-contributing.md index 46acebb..ec70267 100644 --- a/docz/docs/09-miscellany/07-contributing.md +++ b/docz/docs/09-miscellany/05-contributing.md @@ -1,5 +1,5 @@ --- -sidebar_position: 7 +sidebar_position: 5 --- # Contributing @@ -91,7 +91,7 @@ On Linux: sudo apt-get install mercurial subversion ``` -On MacOS, install using [Homebrew](https://brew.sh/): +On MacOS, install using [`brew`](https://brew.sh/): ```bash brew install mercurial subversion @@ -128,7 +128,7 @@ cd modules; make; cd .. make dist ``` -4) (For deno testing) Install deno: +4) (For Deno testing) Install Deno: ```bash curl -fsSL https://deno.land/install.sh | sh diff --git a/docz/docs/09-miscellany/08-license.md b/docz/docs/09-miscellany/07-license.md similarity index 99% rename from docz/docs/09-miscellany/08-license.md rename to docz/docs/09-miscellany/07-license.md index 9892c43..58c769c 100644 --- a/docz/docs/09-miscellany/08-license.md +++ b/docz/docs/09-miscellany/07-license.md @@ -1,5 +1,5 @@ --- -sidebar_position: 8 +sidebar_position: 7 hide_table_of_contents: true --- diff --git a/docz/docs/09-miscellany/09-references.md b/docz/docs/09-miscellany/08-references.md similarity index 80% rename from docz/docs/09-miscellany/09-references.md rename to docz/docs/09-miscellany/08-references.md index 00238ae..a53dbff 100644 --- a/docz/docs/09-miscellany/09-references.md +++ b/docz/docs/09-miscellany/08-references.md @@ -1,5 +1,5 @@ --- -sidebar_position: 9 +sidebar_position: 8 hide_table_of_contents: true --- @@ -9,10 +9,9 @@ Some of our original research is documented at 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 - + - Worksheet File Format (From Lotus) December 1984 + - Open Document Format for Office Applications Version 1.2 (29 September 2011) + - ISO/IEC 29500:2012(E) "Information technology — Document description and processing languages — Office Open XML File Formats" ## Open Specifications Promise @@ -43,4 +42,10 @@ to sue. The documentation that falls under the promise are listed below. - `XLS`: Microsoft Office Excel 97-2007 Binary File Format Specification - `RTF`: Rich Text Format -
\ No newline at end of file + + + +## Other Resources + +- ISBN 1556155212 "Excel Software Development Kit Version 4" +- ISBN 1556156324 "Excel Developer's Kit Version 5" diff --git a/docz/docs/index.md b/docz/docs/index.md index f2a9a1f..75d76fb 100644 --- a/docz/docs/index.md +++ b/docz/docs/index.md @@ -61,7 +61,7 @@ document.getElementById("sheetjsexport").addEventListener('click', function() { -
Live Example (click to show) +
Live Example (click to hide) ```jsx live /* The live editor requires this function wrapper */ @@ -133,7 +133,7 @@ support for CSS styling and rich text.
-
Live Example (click to hide) +
Live Example (click to show) ```jsx live /* The live editor requires this function wrapper */