---
title: Data in Quasar Apps
sidebar_label: Quasar
description: Build data-intensive mobile apps with Quasar and Cordova. Seamlessly integrate spreadsheets into your app using SheetJS. Let data in your Excel spreadsheets shine.
pagination_prev: demos/static/index
pagination_next: demos/desktop/index
sidebar_position: 3
sidebar_custom_props:
summary: VueJS + Web View
---
import current from '/version.js';
import CodeBlock from '@theme/CodeBlock';
[Quasar](https://quasar.dev/) is a VueJS framework for building iOS and Android
apps with the Cordova platform.
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
data from spreadsheets.
This demo uses Quasar and SheetJS to process data and generate spreadsheets.
We'll explore how to load SheetJS in an Quasar app and use Quasar and Cordova
features to extract data from, and write data to, spreadsheets on the device.
The ["Demo"](#demo) creates an app that looks like the screenshots below:
iOS |
Android |

|

|
:::note Tested Deployments
This demo was tested in the following environments:
**Real Devices**
| OS | Device | Quasar | Date |
|:-----------|:--------------------|:---------|:-----------|
| Android 34 | NVIDIA Shield | `2.18.1` | 2025-04-17 |
| iOS 15.1 | iPad Pro | `2.18.1` | 2025-04-17 |
**Simulators**
| OS | Device | Quasar | Dev Platform | Date |
|:-----------|:--------------------|:---------|:-------------|:-----------|
| Android 35 | Pixel 9 Pro XL | `2.18.1` | `darwin-arm` | 2025-04-17 |
| iOS 18.2 | iPhone 16 Pro Max | `2.18.1` | `darwin-arm` | 2025-04-17 |
| Android 36 | Pixel 9 Pro XL | `2.18.1` | `win11-x64` | 2025-04-17 |
:::
## Integration Details
The [SheetJS NodeJS Module](/docs/getting-started/installation/nodejs) can be
imported from any component or script in the app.
This demo will use the Quasar ViteJS starter project with VueJS and Cordova.
The starter places the backing Cordova project in the `src-cordova` folder.
The complete solution uses `cordova-plugin-file` for file operations. It can
be installed from the Cordova folder:
```bash
cd src-cordova
cordova plugin add cordova-plugin-file
cd ..
```
### Reading data
The `QFile`[^1] component presents an API reminiscent of File Input elements:
```html
```
When binding to the `input` element, the callback receives an `Event` object.
Using standard DOM operations, the file data can be pulled into an `ArrayBuffer`
and parsed using the SheetJS `read` method[^2]. `read` returns a workbook[^3]
object that holds data and metadata for each worksheet.
This snippet reads a workbook, pulls the first worksheet, generates an array of
objects using the SheetJS `sheet_to_json`[^4] method, and updates state:
```ts
import { read } from 'xlsx';
// assuming `todos` is a standard VueJS `ref`
async function updateFile(v) { try {
// `v.target.files[0]` is the desired file object
const files = (v.target as HTMLInputElement).files;
if(!files || files.length == 0) return;
// read first file
const wb = read(await files[0].arrayBuffer());
// get data of first worksheet as an array of objects
const data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
// update state
todos.value = data.map(row => ({id: row.Index, content: row.Name}));
} catch(e) { console.log(e); } }
```
### Writing data
Starting from an array of objects, the SheetJS `json_to_sheet` method[^5]
generates a SheetJS worksheet object. The `book_append_sheet` and `book_new`
helper functions[^6] create a SheetJS workbook object that can be exported:
```js
import { utils } from 'xlsx';
// assuming `todos` is a VueJS ref whose value is an array of objects
const ws = utils.json_to_sheet(todos.value);
const wb = utils.book_new();
utils.book_append_sheet(wb, ws, "SheetJSQuasar");
```
The SheetJS `write` function[^7] with the option `type: "buffer"` will generate
`Uint8Array` objects that can be converted to blobs and exported:
```js
import { write } from 'xlsx';
// on iOS and android, `XLSX.write` with type "buffer" returns a `Uint8Array`
const u8: Uint8Array = write(wb, {bookType: "xlsx", type: "buffer"});
```
The `cordova-plugin-file` API writes the data to the filesystem. The code uses
the File and Directory Entries API[^8]:
```ts
// Request filesystem access for persistent storage
window.requestFileSystem(window.PERSISTENT, 0, function(fs) {
// Request a handle to "SheetJSQuasar.xlsx", making a new file if necessary
fs.root.getFile("SheetJSQuasar.xlsx", {create: true}, entry => {
// Request a FileWriter for writing data
entry.createWriter(writer => {
// The FileWriter API needs an actual Blob
const data = new Blob([u8], {type: "application/vnd.ms-excel"});
// This callback is called if the write is successful
writer.onwriteend = () => {
// TODO: show a dialog
};
// writer.onerror will be invoked if there is an error in writing
// write the data
writer.write(data);
});
});
});
```
## Demo
The demo draws from the ViteJS example. Familiarity with VueJS and TypeScript
is assumed.
### Platform Setup
0) Ensure all of the dependencies are installed. Install the CLI globally:
```bash
npm i -g @quasar/cli cordova
```
:::note pass
In some systems, the command must be run as the root user:
```bash
sudo npm i -g @quasar/cli cordova
```
:::
Installation Notes (click to show)
Quasar requires Java 17
### Base Project
1) Create a new app:
```bash
npm init quasar
```
When prompted:
- "What would you like to build?": `App with Quasar CLI, let's go!`
- "Project folder": `SheetJSQuasar`
- "Pick script type": `Typescript`
- "Pick Quasar App CLI variant": `Quasar App CLI with Vite`
- "Package name": (press Enter, it will use the default `sheetjsquasar`)
- "Project product name": `SheetJSQuasar`
- "Project description": `SheetJS + Quasar`
- "Pick a Vue component style": `Composition API with