EatSheet.xlsx
npm
A1
=PREVIEW(file, in="vue")

Preview an XLSX file in Vue

To preview an XLSX file in Vue, open it with EatSheet in a post-flush watcher and put the returned HTML in a scrolling element. Parsing runs in a Web Worker, and only the rows in view are rendered.

1. Install it

npm install eatsheet

2. Add ExcelPreview.vue

<script setup>
import { ref, watchEffect } from 'vue';
import { openWorkbook } from 'eatsheet/worker';
import 'eatsheet/eatsheet.css';

const props = defineProps(['file']);
const box = ref(null);
const error = ref(null);

watchEffect(onCleanup => {
  const file = props.file;
  const element = box.value;
  if (!file || !element) return;

  let book, gone = false, frame = 0;
  error.value = null;

  const draw = async () => {
    const { html } = await book.render(0, { offset: element.scrollTop });
    if (!gone) element.innerHTML = html; // EatSheet escapes cell content
  };
  const onScroll = () => {
    cancelAnimationFrame(frame);
    frame = requestAnimationFrame(() => draw().catch(failure => (error.value = failure)));
  };

  openWorkbook(file).then(opened => {
    if (gone) return opened.close();
    book = opened;
    element.addEventListener('scroll', onScroll);
    return draw();
  }).catch(failure => { if (!gone) error.value = failure; });

  onCleanup(() => {
    gone = true;
    cancelAnimationFrame(frame);
    element.removeEventListener('scroll', onScroll);
    book?.close();
  });
});
</script>

<template>
  <p v-if="error" role="alert">Couldn't open this file: {{ error.code ?? error.message }}</p>
  <div v-show="!error" ref="box" tabindex="0" style="height: 480px; overflow: auto"></div>
</template>

3. Use it with a file input

<script setup>
import { ref } from 'vue';
import ExcelPreview from './ExcelPreview.vue';

const file = ref(null);
</script>

<template>
  <input type="file" accept=".xlsx,.csv,.tsv" @change="file = $event.target.files[0]">
  <ExcelPreview v-if="file" :file="file" />
</template>
Tested on November 7, 2026 with EatSheet 0.2.3 and Vue 3.5 and Vite 8, in development and production: a valid file, a corrupt file, then a valid file again.