Markdown Table Generator

Paste a spreadsheet range or a CSV and get an aligned Markdown table, with pipes inside cells escaped so the table does not silently break.

Enable JavaScript to customise; default output below.

Copying a range out of a spreadsheet gives you tab separated data, which is the default.

Separated by

Comma and semicolon honour double quotes, so a cell containing the separator survives.

Column alignment

Written into the separator row as colons. "none" leaves the renderer to decide.

Live preview table.md
| Plan | Price                | Seats |
| :--- | :------------------- | :---- |
| Free | $0                   | 1     |
| Pro  | $99 \| billed yearly | 5     |
| Team | $299                 | 25    |

Rows                   3
Columns                3
Header row             first row of your data
Cells needing escapes  1

The separator row under the header is what makes this a table rather
than a paragraph, and it has to have one cell per column. That is the
usual reason a pasted Markdown table renders as text.

A pipe inside a cell was escaped and a newline became a <br>, because
both end a cell in Markdown. This is the input that most often turns a
valid table into a broken one, and a spreadsheet produces it regularly.

Output is valid and updates as you type.

Markdown tables are not difficult, they are tedious. The pipes have to line up if the source is going to be readable, the separator row under the header has to have one cell per column or the whole table renders as a paragraph, and a pipe inside a cell ends the cell.

That last one is the reason to use a tool. A price column reading $99 | billed yearly is exactly what a spreadsheet produces, and pasting it into a table adds a column to one row, which breaks the table in a way that is hard to spot.

How to use

  1. Copy a range out of a spreadsheet, which gives you tab separated data, and paste it in.
  2. Pick the alignment.
  3. Copy the table.

Example

Three columns from a spreadsheet, one of them containing a pipe:

| Plan | Price                | Seats |
| :--- | :------------------- | :---- |
| Free | $0                   | 1     |
| Pro  | $99 \| billed yearly | 5     |
| Team | $299                 | 25    |

The pipe is escaped as \|, the columns are padded to their widest cell, and the separator row is padded with them so the source reads as a grid. The padding makes no difference to what renders; it makes all the difference to editing the table later.

Pitfalls

A table with no header row is not a table. Markdown requires the separator row, and the separator row has to follow a header. If your data has no header, the tool generates one, because the alternative is a table that renders as text.

The separator row’s cell count has to match. Four columns of data and three cells of dashes gives you a paragraph of pipes. This is the most common reason a hand-written table does not render.

A pipe inside a cell has to be escaped. \| renders as a pipe and does not end the cell. Nothing warns you about this; the row just gains a column.

A newline inside a cell is not possible. Markdown rows are lines. <br> is the usual workaround and it is what this tool inserts, because a cell containing a line break is common in exported data.

Alignment is per column and lives in the separator row. :--- left, :---: centre, ---: right. Nothing else in the table carries alignment, and a renderer that ignores it is within its rights.

Not every Markdown flavour has tables. They are a GitHub Flavored Markdown extension, in CommonMark only by convention. GitHub, GitLab, most static site generators and the WordPress block editor’s Markdown paste all support them; a strict CommonMark renderer does not.

Compatibility

Everything runs in the browser: nothing is uploaded and nothing is stored.

Comma and semicolon separated input is parsed with quote handling, so a cell wrapped in double quotes can contain the separator and a doubled "" becomes one quote. That is the CSV convention, and it is what a spreadsheet exports.

Column widths are measured in Unicode code points rather than UTF-16 units, so a cell containing an emoji or a CJK character does not throw the padding out by one. It is worth saying that perfect alignment is impossible in the general case: a double-width CJK character occupies two columns in a monospaced font and counts as one code point, so a table mixing scripts will look slightly uneven however it is padded. The renderer does not care either way.

The output is GitHub Flavored Markdown, which is what GitHub, GitLab, Obsidian, Notion’s importer, Docusaurus and most other tools expect.

Frequently asked questions

How do I copy a table out of Excel or Google Sheets?
Select the range and copy. Both put tab separated text on the clipboard, which is the default here. Paste it straight in.
Can I turn a Markdown table back into a spreadsheet?
Copy the table, strip the pipes, and paste. There is no reverse mode here because a Markdown table pasted into a spreadsheet is usually one column, and fixing that is the spreadsheet’s text-to-columns feature rather than a converter.
Why is my table not rendering?
Nine times out of ten the separator row. It must be the second line, it must have one cell per column, and it must contain only dashes and colons.
Does the padding matter?
Not to the renderer. It matters to whoever edits the file next, which is usually you, and an unaligned table is where cell-count mistakes hide.
Can cells contain formatting?
Yes: bold, italics, code spans and links all work inside a cell, and the tool leaves them alone. Only pipes and newlines are escaped, because only those two change the structure.
Weekly drops

New tools, when there are new tools

One email when something worth using ships. No schedule to fill, so no filler.

Your address goes nowhere else, and one click unsubscribes.