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

Preview an XLSX file in Electron

To preview an XLSX file in Electron, build your renderer with Vite using relative paths and load the result from disk. The file stays on the device, and the worker keeps the window responsive.

1. Install it

npm install eatsheet
npm install --save-dev electron vite

2. Add vite.config.js

import { defineConfig } from 'vite';

// Relative paths, so the built page and its worker load from disk
export default defineConfig({ base: './' });

3. Add main.js

import { app, BrowserWindow } from 'electron';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';

const here = dirname(fileURLToPath(import.meta.url));

app.whenReady().then(() => {
  const window = new BrowserWindow({ width: 1200, height: 800 });
  window.loadFile(join(here, 'dist/index.html'));
});

app.on('window-all-closed', () => app.quit());

4. Add index.html

<!doctype html>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; style-src 'self' 'unsafe-inline'; worker-src 'self'">
<title>Excel preview</title>
<input type="file" accept=".xlsx,.csv,.tsv">
<p role="alert" hidden></p>
<div id="sheet" tabindex="0" style="height: 480px; overflow: auto"></div>
<script type="module" src="/renderer.js"></script>

5. Add renderer.js

import { openWorkbook } from 'eatsheet/worker';
import 'eatsheet/eatsheet.css';

const input = document.querySelector('input');
const message = document.querySelector('[role=alert]');
const container = document.querySelector('#sheet');
let book;

const draw = async () => {
  container.innerHTML = (await book.render(0, { offset: container.scrollTop })).html;
};
container.addEventListener('scroll', () => {
  if (book) requestAnimationFrame(draw);
});

input.addEventListener('change', async () => {
  book?.close();
  book = null;
  message.hidden = true;
  container.hidden = false;
  try {
    book = await openWorkbook(input.files[0]);
    container.scrollTop = 0;
    await draw();
  } catch (error) {
    message.textContent = `Couldn't open this file: ${error.code ?? error.message}`;
    message.hidden = false;
    container.hidden = true;
  }
});

6. Build and run

Set "type": "module" and "main": "main.js" in package.json, then run:
npx vite build
npx electron .
EatSheet writes workbook styles as inline styles, so the policy needs style-src 'unsafe-inline'. To package the app, use a tool such as Electron Forge and include dist.
Tested on November 7, 2026 with EatSheet 0.2.3 and Electron 45 and Vite 8, on macOS, from a production build: a valid file, a corrupt file, then a valid file again.