diff --git a/docz/docs/03-example.mdx b/docz/docs/03-example.mdx index eb4c3a4..1ec78d5 100644 --- a/docz/docs/03-example.mdx +++ b/docz/docs/03-example.mdx @@ -245,7 +245,7 @@ $ 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 +```js title="snippet.js" const XLSX = require("xlsx"); (async() => { @@ -293,7 +293,7 @@ $ npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz The differences in the script are highlighted below. -```js +```js title="snippet.js" const XLSX = require("xlsx"); // highlight-next-line const axios = require("axios"); @@ -338,7 +338,7 @@ const axios = require("axios"); Save the following script to `snippet.ts` and run with `deno run --allow-net --allow-write snippet.ts`: -```js +```js title="snippet.ts" // @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'; @@ -372,4 +372,46 @@ XLSX.writeFile(workbook, "Presidents.xlsx"); ``` + + +Download to `xlsx.mjs` + +Save the following script to `snippet.js` and run with `bun snippet.js`: + +```js title="snippet.js" +import * as XLSX from './xlsx.mjs'; +import * as fs from 'fs'; +XLSX.set_fs(fs); + +/* 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.xlsx */ +XLSX.writeFile(workbook, "Presidents.xlsx"); +``` + + + \ No newline at end of file diff --git a/docz/docs/06-solutions/01-input.md b/docz/docs/06-solutions/01-input.md index ecd7492..209f06e 100644 --- a/docz/docs/06-solutions/01-input.md +++ b/docz/docs/06-solutions/01-input.md @@ -78,21 +78,6 @@ set_fs(fs); const workbook = readFile("test.xlsx"); ``` - - - -`readFile` uses `Deno.readFileSync` 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';
-
-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 -
@@ -177,6 +162,21 @@ var workbook = XLSX.readFile(thisFile.absoluteURI); The [`extendscript` demo](../getting-started/demos/extendscript) includes a more complex example. + + + +`readFile` uses `Deno.readFileSync` 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';
+
+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 +
diff --git a/docz/docs/06-solutions/05-output.md b/docz/docs/06-solutions/05-output.md index fc9043b..53a9f90 100644 --- a/docz/docs/06-solutions/05-output.md +++ b/docz/docs/06-solutions/05-output.md @@ -278,6 +278,141 @@ fs.write("SheetJSansHead.xlsb", bin, "wb"); +### Example: Server Responses + +This example focuses on responses to network requests in a server-side platform +like NodeJS. While files can be generated in the web browser, server-side file +generation allows for exact audit trails and has better mobile user support. + +:::caution + +Production deployments should use a server framework like ExpressJS. These +snippets use low-level APIs for illustration purposes. + +::: + +The `Content-Type` header should be set to `application/vnd.ms-excel` for Excel +exports including XLSX. The default `application/octet-stream` can be used, but +iOS will not automatically suggest to open files in Numbers or Excel for iOS + +The `Content-Disposition` header instructs browsers to download the response +into a file. The header can also include the desired file name. + + + + +NodeJS `http.ServerResponse#end` can accept `Buffer` objects. `XLSX.write` with +`buffer` type returns `Buffer` objects. + +```js +/* generate Buffer */ +const buf = XLSX.write(wb, { type:"buffer", bookType:"xlsx" }); + +/* prepare response headers */ +res.statusCode = 200; +res.setHeader('Content-Disposition', 'attachment; filename="SheetJSNode.xlsx"'); +res.setHeader('Content-Type', 'application/vnd.ms-excel'); +res.end(buf); +``` + +
Complete Example (click to show) + +Install the library with + +```bash +npm i https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz +``` + +Save the following script to `node.js` and run with `node node.js`: + +```js title="node.js" +const http = require('http'); +const XLSX = require('xlsx'); + +const hostname = '127.0.0.1'; +const port = 7262; + +/* fixed sample worksheet */ +const wb = XLSX.utils.book_new(); +XLSX.utils.book_append_sheet(wb, XLSX.utils.aoa_to_sheet([ + ["a","b","c"], [1,2,3] +]), "Sheet1"); + +const server = http.createServer((req, res) => { + const buf = XLSX.write(wb, { type:"buffer", bookType:"xlsx" }); + res.statusCode = 200; + res.setHeader('Content-Disposition', 'attachment; filename="SheetJSNode.xlsx"'); + res.setHeader('Content-Type', 'application/vnd.ms-excel'); + res.end(buf); +}); + +server.listen(port, hostname, () => { + console.log(`Server running at http://${hostname}:${port}/`); +}); +``` + +
+ +
+ + + + + + + +Bun responses are expected to be `Response` objects. `XLSX.write` with `buffer` +type returns `Buffer` objects that can be used in the `Response` constructor. + +```js +/* generate Buffer */ +const buf = XLSX.write(wb, { type:"buffer", bookType:"xlsx" }); +/* return Response */ +return new Response(buf, { + headers: { + "Content-Type": "application/vnd.ms-excel", + "Content-Disposition": 'attachment; filename="SheetJSBun.xlsx"' + } +}); +``` + +
Complete Example (click to show) + +Download [`xlsx.mjs`](https://cdn.sheetjs.com/xlsx-latest/package/xlsx.mjs). +Save the following script to `bun.js` and run with `bun bun.js`. Open a web +browser and access to download the exported workbook. + +```js title="bun.js" +import * as XLSX from "./xlsx.mjs"; + +/* fixed sample worksheet */ +const wb = XLSX.utils.book_new(); +XLSX.utils.book_append_sheet(wb, XLSX.utils.aoa_to_sheet([ + ["a","b","c"], [1,2,3] +]), "Sheet1"); + +export default { + port: 7262, + fetch(request) { + /* generate Buffer */ + const buf = XLSX.write(wb, {type:"buffer", bookType:"xlsx"}); + /* return Response */ + return new Response(buf, { + headers: { + "Content-Type": "application/vnd.ms-excel", + "Content-Disposition": 'attachment; filename="SheetJSBun.xlsx"' + } + }); + }, +}; +``` + +
+ +
+
+ + ### Example: Remote File This example focuses on uploading files ("Ajax" in browser parlance) using APIs