docs.sheetjs.com/docz/static/tauri/App.vue
2024-05-28 01:20:05 -04:00

186 lines
4.6 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import { ref, shallowRef, onMounted } from 'vue'
import { read, write, utils, version, WorkBook } from 'xlsx';
import { DialogFilter, message, open, save } from '@tauri-apps/api/dialog';
import { fetch, ResponseType } from '@tauri-apps/api/http';
import { readBinaryFile, writeBinaryFile } from '@tauri-apps/api/fs';
const ver = ref(version);
const data = shallowRef<any[][]>([[]])
const origin = ref("");
const update = (wb: WorkBook) => {
const ws = wb.Sheets[wb.SheetNames[0]];
data.value = utils.sheet_to_json<any[]>(ws, { header: 1})
};
/* Download from https://docs.sheetjs.com/pres.numbers */
onMounted(async() => {
try {
origin.value = "https://docs.sheetjs.com/pres.numbers";
const response = await fetch<Uint8Array>("https://docs.sheetjs.com/pres.numbers", { method: "GET", responseType: ResponseType.Binary });
const wb = read(new Uint8Array(response.data));
update(wb);
} catch(e) { await message((e as Error).message || (e as string), { title: "Fetch Error", type: "error"}); }
});
const filters: DialogFilter[] = [
{name: "Excel Binary Workbook", extensions: ["xlsb"]},
{name: "Excel Workbook", extensions: ["xlsx"]},
{name: "Excel 97-2004 Workbook", extensions: ["xls"]},
{name: "Excel 2003 XML Spreadsheet", extensions: ["xml"]},
{name: "Symbolic Link", extensions: ["slk"]},
{name: "Flat OpenDocument Spreadsheet", extensions: ["fods"]},
{name: "OpenDocument Spreadsheet", extensions: ["fods"]},
// ...
];
/* Load from File */
const openFile = async() => {
try {
const selected = await open({
title: "Open Spreadsheet",
multiple: false,
directory: false,
filters
}) as string;
const d = await readBinaryFile(selected);
const wb = read(d);
update(wb);
origin.value = selected;
} catch(e) { await message((e as Error).message || (e as string), { title: "Load Error", type: "error"}); }
};
/* Save to File */
const saveFile = async() => {
try {
const selected = await save({
title: "Save to Spreadsheet",
filters
});
if(!selected) throw new Error("No file selected");
const ws = utils.aoa_to_sheet(data.value);
const wb = utils.book_new();
utils.book_append_sheet(wb, ws, "SheetJSTauri");
const d = write(wb, {type: "buffer", bookType: selected.slice(selected.lastIndexOf(".") + 1) as any}) as Uint8Array;
await writeBinaryFile(selected, d);
await message(`File saved to ${selected}`);
} catch(e) { await message((e as Error).message || (e as string), { title: "Save Error", type: "error"}); }
};
</script>
<template>
<div class="root">
<h1><a href="https://sheetjs.com" target="_blank">
<img src="https://sheetjs.com/sketch128.png" class="logo" alt="SheetJS" />
SheetJS × Tauri {{ ver }}</a></h1>
<div class="centre"><button type="button" @click="openFile()">Load Data</button> or
<button type="button" @click="saveFile()">Save Data</button></div>
<p class="centre"><b class="centre">Data from {{ origin }}</b></p>
<table class="center"><tbody>
<tr v-for="(row, index) in data" v-bind:key="index">
<td v-for="(cell, col) in row" v-bind:key="col">
{{ cell }}
</td>
</tr>
</tbody></table>
</div>
</template>
<style scoped>
.logo {
padding: 0px;
height: 64px; width: 64px;
vertical-align: middle;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.centre { text-align: center; }
table.center {
margin-left: auto;
margin-right: auto;
}
.root {
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 24px;
font-weight: 400;
color: #0f0f0f;
background-color: #f6f6f6;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
h1 {
text-align: center;
}
input,
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
color: #0f0f0f;
background-color: #ffffff;
transition: border-color 0.25s;
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
}
button {
cursor: pointer;
}
button:hover {
border-color: #396cd8;
}
button:active {
border-color: #396cd8;
background-color: #e8e8e8;
}
input,
button {
outline: none;
}
@media (prefers-color-scheme: dark) {
.root {
color: #f6f6f6;
background-color: #2f2f2f;
}
a:hover {
color: #24c8db;
}
input,
button {
color: #ffffff;
background-color: #0f0f0f98;
}
button:active {
background-color: #0f0f0f69;
}
}
</style>