Markdown Table to CSV Converter
Get the numbers back out of a document. Paste the table from a README, a wiki page or a chat answer and download a CSV that a spreadsheet will open.
To convert a Markdown table to CSV, paste it into the box above. The header row and the row of dashes underneath it are recognised, the dashes are discarded as punctuation rather than treated as data, escaped pipes stay inside their cells, a br becomes a real line break, and short rows are padded and reported. Download the CSV or copy it.
Want to sort or total the numbers? Open the app
Where these tables come from now
Two years ago the answer was mostly READMEs. It still is, partly, but the volume has shifted: a Markdown table is what a language model produces when you ask it to compare five things, what a documentation site renders, what Notion and Obsidian export, and what a wiki page holds after somebody pasted a spreadsheet into it.
So the table you have is often the only copy of the data. The original spreadsheet is gone, or was never real, and re-typing thirty rows to add up one column is an unreasonable amount of work for a question that takes five seconds to ask.
This is the way back. Paste the document, get the rows, open them anywhere.
Worked example, with the awkward bits included
A release table of the sort that actually turns up, three hazards and all:
| service | version | released | replicas | notes |
|:--------|--------:|:--------:|---------:|:------|
| billing-api | 2.4.1 | 2026-01-08 | 6 | rollout paused<br>resumed 09 Jan |
| web-frontend | 5.0.0 | 2026-01-12 | 4 | canary 10% \| full 14 Jan |
| search-index | 1.19.3 | 2026-01-15 | 12 | |
And the CSV:
service,version,released,replicas,notes
billing-api,2.4.1,2026-01-08,6,"rollout paused
resumed 09 Jan"
web-frontend,5.0.0,2026-01-12,4,canary 10% | full 14 Jan
search-index,1.19.3,2026-01-15,12,
Three things to notice. The <br> became a real newline inside a quoted CSV field, which is what a spreadsheet shows as two lines in one cell. The escaped \| came back as a plain pipe rather than splitting the row into six columns. And the alignment row with its colons never appears in the output, because it is punctuation.
The four things that make this harder than splitting on pipes
- The outer pipes are optional. GitHub accepts
a | bwith no leading or trailing pipe. Splitting a fully-piped row on the pipe character gives you two phantom empty columns at the ends, which is why a naive converter produces a CSV with a blank first column. - A pipe can be escaped.
canary 10% \| fullis one cell. The backslash has to be honoured during the split, not removed afterwards, or the row is already broken by the time anyone notices. - A cell can hold a line break. Markdown has no row continuation, so
<br>is the only way to write one, and it means a real newline. Dropping it silently joins two lines with a space and changes your data. - Rows are often ragged. Hand-edited tables lose a trailing pipe constantly. A short row is padded to the header width and you get a note saying how many; the alternative, dropping the row or truncating the header, loses data.
Several tables, and the code blocks that are not tables
A README usually has more than one table. Each one is found, labelled with the nearest heading above it, and listed under the result with its row and column counts. The first converts on arrival and switching is one click.
Tables inside a fenced code block are skipped, which is the difference between reading a document and scraping it. Documentation about Markdown is full of example tables inside fences, and pulling those in as data is both wrong and confusing. If any were skipped, a note says how many, so you are never left wondering where a table went.
What comes out, and what to do next
The CSV is comma-separated with minimal quoting by default: a field is quoted only when it contains a comma, a quote or a newline. If the tool on the other end wants semicolons, tabs or pipes, the separator is a dropdown, and the quoting can be forced on for every field if something downstream is strict about it.
Cell text is trimmed of the spaces that made the source line up, since those were formatting rather than data. What is not touched is anything inside the value: a double space in the middle of a sentence survives.
Frequently Asked Questions
Do I have to paste only the table, or can I paste the whole document?
The whole document. Prose, headings and lists are all ignored, and only the tables are read. That is usually easier than trying to select exactly the right lines out of a long README.
What happens to the row of dashes?
It is recognised as the alignment row and discarded. The colons in it set left, center or right alignment, which is presentation rather than data, so a note tells you how many columns were aligned and the alignment itself is not carried into the CSV.
My table has escaped pipes in a cell. Will that break it?
No. A backslash before a pipe is honoured during the split, so canary 10% \| full stays one cell rather than becoming two columns. Handling this after the split rather than during it is the usual reason a converter gets it wrong.
One of my rows is missing its last cell. What happens?
It is padded to the header width and a note says how many rows were padded. Nothing is dropped and the header is not truncated. Hand-edited tables lose a trailing pipe all the time, and losing a row over it would be worse than saying so.
There are three tables in my README. Which one do I get?
The first, immediately, and the other two appear as a picker underneath, each labelled with the heading above it. Tables inside fenced code blocks are treated as examples and skipped, with a note if any were.
Does a table with no outer pipes work?
Yes. GitHub allows a | b with no leading or trailing pipe and so does this. A converter that splits naively on the pipe character produces phantom empty columns on a fully-piped table, which is the other half of the same problem.
Related
Get the numbers out of the document
Paste the table, download the CSV. Escaped pipes, line breaks and ragged rows all handled.
Back to the converter