--- 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
Local file in a NodeJS server (click to show) `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); ```
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: - `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 */ ```
Download a file in legacy browsers (click to show) `XLSX.writeFile` techniques work for most modern browsers as well as older IE. For much older browsers, there are workarounds implemented by wrapper libraries. [`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.
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): ```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); ```
PhantomJS (Headless Webkit) File Generation (click to show) 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".
The [included demos](https://github.com/SheetJS/SheetJS/tree/master/demos/) cover mobile apps and other special deployments. ### Writing Examples - exporting an HTML table - 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`.
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. ### 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. is a 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` 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 ; } ```
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/).
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.
Numerical Computations with TensorFlow.js (click to show) `@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.
### 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 `` 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:
Vanilla JS + HTML fetch workbook and generate table previews (click to show) ```html
```
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 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 => (<>

name

)); } ``` 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: ```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: `

{{ ws.name }}

` }; ``` The [`vuejs` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/vue) includes more React examples.
### 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.