HTML · Markdown · CSV · JSON · Paste to import

Table Generator

Build tables in a spreadsheet-like editor and export as HTML, Markdown, CSV, or JSON. Paste existing CSV data to import instantly.


            
            
          

Build tables once, use everywhere

Switching between formats is tedious. This tool lets you edit in a familiar spreadsheet-like grid and export the same data in whatever format your destination needs.

🌐

HTML tables

Generates clean, semantic HTML with <thead>/<tbody> and proper <th scope="col"> for accessibility. Paste directly into WordPress, Webflow, or any CMS.

📝

Markdown tables

GFM (GitHub Flavored Markdown) table syntax — compatible with GitHub, GitLab, Notion, Obsidian, and most static site generators like Jekyll and Hugo.

📊

CSV & JSON

CSV for Excel/Sheets import, JSON (array of objects) for use in REST APIs, JavaScript apps, or data visualization tools.

Markup that makes a table usable

A data table needs more than rows and cells to be comprehensible to a screen reader. Header cells must be <th> rather than styled <td>, and each needs a scope attribute — scope="col" or scope="row" — so assistive technology can announce the relevant headers as the user moves between cells. Without it, a cell is read as a bare value with no indication of what it measures.

A <caption> gives the table a name, announced when a screen reader encounters it and used when navigating between tables on a page. It is far more useful than a heading above the table, because it is programmatically associated.

Grouping rows into <thead>, <tbody> and <tfoot> conveys structure and has a practical benefit: browsers repeat <thead> at the top of each printed page. For complex tables where a cell relates to headers that scope cannot express, headers and id attributes make the relationship explicit — though a complex table is usually better split into several simple ones.

Never use tables for layout

Layout tables were standard practice in the 1990s and are now a genuine accessibility failure. A screen reader announces a table and its dimensions, then reads cell by cell — so a page laid out in a table is announced as a data structure with no data, and navigation commands intended for tabular data produce nonsense.

Grid and flexbox do everything layout tables did, with less markup and responsive behaviour that tables cannot match. The one legitimate exception is HTML email, where client support is so poor that table-based layout remains necessary — and there the tables should carry role="presentation" so assistive technology ignores their structure.

The converse mistake matters too: building a data table out of <div> elements because it is easier to style. That discards all the semantics, and rebuilding them with ARIA roles is more work than using the right elements. If the content is tabular, use a table.

Tables on small screens

Tables do not fit narrow viewports, and every solution is a compromise. Horizontal scrolling is the simplest and preserves the structure entirely: wrap the table in a container with overflow-x: auto. Make the container focusable with tabindex="0" and give it an accessible name, otherwise keyboard users cannot scroll it.

Reflowing each row into a stacked block works for tables with few columns, using a data attribute on each cell to display its header via CSS. It reads well on a phone and breaks down entirely for wide tables, where the stacked result is enormously long.

Prioritising columns — hiding less important ones below a breakpoint — keeps the table shape but withholds data, so it is only acceptable if the hidden columns are genuinely secondary or can be revealed. Whichever approach you choose, resist reducing font size to fit: text below about 16 px triggers zoom on iOS and is hard to read, which trades one problem for a worse one. For alignment, right-align numbers so digits line up by place value, left-align text, and use tabular figures where the typeface offers them so columns of numbers do not shift.

Frequently Asked Questions

How do I import existing data?

Click "Paste CSV" and paste comma-separated values. The first row becomes headers if the "Header row" checkbox is on. Quoted fields with commas are handled correctly.

What Markdown flavor does this use?

GFM (GitHub Flavored Markdown), which is the most widely supported Markdown table format. Columns are separated by pipes (|) with a separator row of dashes on the second line.

Can I export just the data, not the headers?

Uncheck "Header row" before exporting. The first row will be treated as data in all export formats.

What does the JSON export look like?

An array of objects where each key is the column header. If "Header row" is off, keys are auto-generated (col1, col2, etc.).

Do I need scope attributes on header cells?

Yes, for any data table. Without scope="col" or scope="row", a screen reader reads cells as bare values with no indication of which header they belong to.

How should tables behave on mobile?

Horizontal scrolling in an overflow-x: auto wrapper is the most robust option — give the wrapper tabindex="0" and a label so keyboard users can scroll it. Avoid shrinking the font below 16 px.