Spreadsheets

The spreadsheet is a whole spreadsheet in one element: a toolbar, a formula bar, sheet tabs and a status bar over a grid that works as Excel does. Type figures and formulas, format them, fill a series with the handle, sort and filter, merge cells, freeze rows and columns, and add notes. The keyboard, the clipboard and the mouse do what your users expect.

Behind it is the formula engine, with 406 Excel functions and dynamic arrays. Excel files open and save with their formulas, number formats, colours, borders, conditional formats and validation, and CSV and JSON go both ways. Everything happens in the page: no server, nothing uploaded.

A sales plan

Six months by product, with totals, growth, a colour scale, data bars and a status column with a list to choose from. Change a figure and everything that depends on it follows. Try the filter buttons in the heading row, the fill handle at the corner of a selection, and Ctrl+C into another spreadsheet.

Download as Excel Download the sheet as CSV Undo
Keyboard: the arrow keys move, Shift extends, Ctrl+arrow jumps to the edge of the data, F2 edits a cell and = starts a formula (the arrow keys then point at cells). Ctrl+B, I and U format, Ctrl+D and R fill down and right, Ctrl+F finds and Ctrl+Page Down moves to the next sheet.
Get the code
<script src="/assets/bmx-components.min.js"></script>

<bmx-spreadsheet id="ss-plan" file-name="sales-plan" label="Sales plan" locale="en-GB" style="inline-size: 100%; --bmx-spreadsheet-height: 34rem"></bmx-spreadsheet>

<script>
  const spreadsheet = document.getElementById('ss-plan');
  spreadsheet.data = [ /* your data */ ];
</script>

Excel files, in and out

Open an Excel workbook from your own computer: its sheets, formulas, number formats, fonts, fills, borders, merged cells, frozen panes, conditional formats and validation come in, and Download saves it back. The file never leaves the page. CSV and tab-separated files open too.

Open a file… Download as Excel
Get the code
<script src="/assets/bmx-components.min.js"></script>

<bmx-spreadsheet id="ss-file" file-name="workbook" label="Your workbook" locale="en-GB" style="inline-size: 100%; --bmx-spreadsheet-height: 26rem"></bmx-spreadsheet>

<script>
  const spreadsheet = document.getElementById('ss-file');
  spreadsheet.data = [ /* your data */ ];
</script>

Functions of your own

A delivery quote that uses two functions this page added: SHIPPING(weight, zone) and VAT(amount). They are typed, completed and checked like the built-in ones, and the cells that use them recalculate when their inputs change. Change a weight or a zone.

Get the code
<script src="/assets/bmx-components.min.js"></script>

<bmx-spreadsheet id="ss-quote" sheet-tabs="false" label="Delivery quote" locale="en-GB" style="inline-size: 100%; --bmx-spreadsheet-height: 20rem"></bmx-spreadsheet>

<script>
  const spreadsheet = document.getElementById('ss-quote');
  spreadsheet.data = [ /* your data */ ];
</script>

Twenty thousand rows

Twenty thousand orders across fifteen columns, with a formula in every row and a colour scale over all of it. Only the cells in view are drawn, so it scrolls as a small sheet does; sort it, filter it, or type in it.

Fill twenty thousand rows
Get the code
<script src="/assets/bmx-components.min.js"></script>

<bmx-spreadsheet id="ss-large" toolbar="false" file-name="orders" label="Orders" locale="en-GB" style="inline-size: 100%; --bmx-spreadsheet-height: 24rem"></bmx-spreadsheet>

<script>
  const spreadsheet = document.getElementById('ss-large');
  spreadsheet.data = [ /* your data */ ];
</script>

Figures to read, not change

With readonly and no toolbar or formula bar, a price list that can be chosen, copied and searched, and not changed.

Get the code
<script src="/assets/bmx-components.min.js"></script>

<bmx-spreadsheet id="ss-prices" readonly toolbar="false" formula-bar="false" sheet-tabs="false" label="Price list" locale="en-GB" style="inline-size: 100%; max-inline-size: 40rem; --bmx-spreadsheet-height: 13rem"></bmx-spreadsheet>

<script>
  const spreadsheet = document.getElementById('ss-prices');
  spreadsheet.data = [ /* your data */ ];
</script>