SheetJS Table to Excel Export and Import (.xlsx) — Free JavaScript Snippet

SheetJS Table to Excel Export and Import (.xlsx) · Tools · Plain HTML, CSS & JS · Live preview

What's included

Features

Real .xlsx output
Not CSV renamed to .xlsx.
Typed cells
Numbers, strings and real dates.
Number formats
Currency, thousands separators and date formats.
Formulas with cached values
Per-row products and a SUM total.
Column widths
Set with !cols in characters.
Multiple sheets
Data plus an About sheet.
Round-trip verification
Write to bytes and read back in the page.
Multi-format import
.xlsx, .xls, .csv and .ods with a sheet picker.

About this UI Snippet

SheetJS — Real Excel Files From the Browser, Formulas and Formats Included

Screenshot of the SheetJS Table to Excel Export and Import (.xlsx) snippet rendered live

"Export to Excel" is one of the most requested features in any admin panel, and a CSV often isn't good enough: numbers lose their formats, dates become text, and totals are frozen values. SheetJS writes genuine .xlsx workbooks in the browser. This snippet exports an inventory table with everything a spreadsheet user expects, and imports workbooks back.

Cells are objects with a type and a format

In SheetJS a worksheet is an object keyed by cell address ("C2"), where each cell has a type t (n for number, s for string, d for date), a value v, and optionally a number format z. Setting z: '"$"#,##0.00' makes Excel display 24.99 as $24.99 while keeping it a number you can sum. Dates are written as real dates with cellDates, formatted with yyyy-mm-dd.

Formulas carry a cached value

A cell with f: 'SUM(F2:F6)' stores a formula Excel recalculates when opening the file. The snippet also sets v, the cached result: readers that don't calculate formulas (including SheetJS itself, and many previews) show that value instead of an empty cell.

The used range and column widths

Cells written directly outside the original array are invisible to Excel unless the sheet's !ref range includes them, so it is widened after the total row is added. !cols sets column widths in characters with wch.

Two sheets

A second "About" sheet records the export time and row count, a common pattern for audit trails.

Round-trip test

XLSX.write(wb, { type: 'array' }) produces the file's bytes without downloading; XLSX.read parses them straight back. The log reports the sheet names, the type and number format of a quantity cell (read back only because cellNF: true is passed — SheetJS drops formats by default), that the date survived as a Date, and the formula with its value — proof of what's inside the file. This also works inside sandboxed previews that block downloads.

Importing

A chosen .xlsx, .xls, .csv or .ods file is read with XLSX.read; sheet_to_json with header: 1 returns arrays of rows, and raw: false applies the file's number formats so values look as they did in Excel. Multi-sheet workbooks get a sheet selector.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Paste this snippet into an AI assistant like Claude and ask it why formulas need a cached value and why !ref must be updated. Ask it to add adding and deleting rows, importing into the editable table with column mapping, exporting only filtered rows, or generating one sheet per category. It can also compare this with exporting CSV and explain when each is appropriate.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build an editable inventory table with Excel export and import using SheetJS (loaded from cdn.sheetjs.com) in plain HTML, CSS and JavaScript.

Requirements:
- Five products with SKU, name, quantity, unit price and last-counted date in an editable table (contenteditable cells, Enter to commit) with a computed stock value column and total.
- Export to .xlsx: numbers as numeric cells with formats (thousands for quantity, currency for price), dates as real dates formatted yyyy-mm-dd, a per-row formula for stock value and a SUM formula total row, each with a cached value; update the sheet's used range and set column widths; add a second "About" sheet with export time and row count; save with compression.
- A round-trip test that writes the workbook to an array, reads it back, and reports sheet names, a price cell's type and format, whether the date is a Date, and the total's formula and value.
- Import .xlsx, .xls, .csv or .ods files, show a sheet selector for multi-sheet workbooks, and render up to 200 rows read-only using formatted values.
- Escape all displayed values and note that sandboxed previews block downloads.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Source Code

Requires
<div class="sx">
  <header class="sx-head">
    <div>
      <h2>Inventory</h2>
      <p>Cells are editable. Export a real .xlsx with number formats, column widths and a live SUM formula — or import a spreadsheet.</p>
    </div>
    <div class="sx-actions">
      <button type="button" id="sxExport">Export .xlsx</button>
      <button type="button" id="sxRound" class="ghost">Round-trip test</button>
      <label class="sx-file ghost">Import .xlsx / .csv<input type="file" id="sxFile" accept=".xlsx,.xls,.csv,.ods"></label>
    </div>
  </header>
  <div class="sx-sheetbar" id="sxSheets" hidden><label>Sheet <select id="sxSheet"></select></label></div>
  <div class="sx-wrap"><table class="sx-table" id="sxTable"></table></div>
  <div class="sx-log" id="sxLog" role="status" aria-live="polite"></div>
</div>

Step by step

How to Use

  1. 1
    Edit cellsClick a cell, type, press Enter; values and totals update.
  2. 2
    Export .xlsxDownloads a two-sheet workbook with formats and formulas.
  3. 3
    Run the round-trip testWrites and re-reads the file to show exactly what it contains.
  4. 4
    Import a spreadsheetChoose .xlsx, .xls, .csv or .ods; pick a sheet if there are several.
  5. 5
    Adapt the columnsEdit COLS for labels, widths and number formats.

Real-world uses

Common Use Cases

Admin dashboards
Export orders, users or inventory.
Reporting tools
Spreadsheets finance teams can work with.
Bulk editing
Export, edit in Excel, import back.
Data migration
Read legacy .xls files in the browser.
Offline apps
No server needed for Excel files.
Related: Papa Parse CSV Validator
Related: CSV Export Table
A simpler CSV-only export: CSV Export Table.

Got questions?

Frequently Asked Questions

With SheetJS, build a worksheet (for example with XLSX.utils.aoa_to_sheet or table_to_sheet), add it to a workbook with book_append_sheet, and call XLSX.writeFile(wb, 'file.xlsx').

Set the z property on a cell to an Excel format string, such as '"$"#,##0.00' for currency or 'yyyy-mm-dd' for dates. The cell must hold a number (or date) for the format to apply.

Set a cell's f property to the formula without the equals sign, for example { t: 'n', f: 'SUM(F2:F6)' }. Also set v to a cached value so viewers that don't calculate show the result.

Excel reads only the range in the sheet's !ref property. When you add cells outside the original range, update !ref with XLSX.utils.encode_range to include them.

The free Community Edition reads and writes data, formats and formulas but not cell styles. Styling requires SheetJS Pro or a styling-capable fork.