docs.sheetjs.com/docz/static/quasar/IndexPage.vue
2025-04-18 00:04:01 -04:00

69 lines
2.2 KiB
Vue

<template>
<q-page class="row items-center justify-evenly">
<q-table :rows="todos" />
<q-btn-group>
<q-file v-model="file" label="Load File" filled label-color="orange" @input="updateFile"/>
<q-btn label="Save File" @click="saveFile" />
</q-btn-group>
</q-page>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { read, write, utils } from 'xlsx';
import { useQuasar } from 'quasar';
import type { Todo } from 'components/models';
const $q = useQuasar();
const todos = ref<Todo[]>([
{ id: 1, content: 'ct1' },
{ id: 2, content: 'ct2' },
{ id: 3, content: 'ct3' },
{ id: 4, content: 'ct4' },
{ id: 5, content: 'ct5' }
]);
const file = ref<File>();
function dialogerr(e: any) { $q.dialog({title: "Error!", message: e?.message || String(e)}); }
function saveFile() {
/* generate workbook from state */
const ws = utils.json_to_sheet(todos.value);
const wb = utils.book_new(ws, "SheetJSQuasar");
const u8: Uint8Array = write(wb, {bookType: "xlsx", type: "buffer"});
const dir: string = $q.cordova.file.documentsDirectory || $q.cordova.file.externalApplicationStorageDirectory;
/* save to file */
window.requestFileSystem(window.PERSISTENT, 0, function(fs) {
try {
fs.root.getFile("SheetJSQuasar.xlsx", {create: true}, entry => {
const msg = `File stored at ${dir} ${entry.fullPath}`;
entry.createWriter(writer => {
try {
const data = new Blob([u8], {type: "application/vnd.ms-excel"});
writer.onwriteend = () => {
try {
$q.dialog({title: "Success!", message: msg});
} catch(e) { dialogerr(e); }
};
writer.onerror = dialogerr;
writer.write(data);
} catch(e) { dialogerr(e); }
}, dialogerr);
}, dialogerr);
} catch(e) { dialogerr(e) }
}, dialogerr);
}
async function updateFile(v: Event) {
try {
const files = (v.target as HTMLInputElement).files;
if(!files || files.length == 0 || !files[0]) return;
const wb = read(await files[0].arrayBuffer());
const data = utils.sheet_to_json<any>(wb.Sheets[wb.SheetNames[0]!]!);
todos.value = data.map(row => ({id: row.Index, content: row.Name}));
} catch(e) { dialogerr(e); }
}
</script>