The README table that ate someone's Tuesday

The pricing table lives in Excel, where pricing tables belong. The README lives in the repo, where READMEs belong. Between them sits a gap exactly one table wide, and the standard crossing procedure, performed in offices worldwide every Tuesday, is: copy the rows, paste them somewhere, and then hand-build the pipe-and-dash scaffolding around each cell while keeping count of columns with a finger on the screen. Twenty rows in, a cell contains a pipe character. The table renders as abstract art. Someone spends the afternoon learning why.

It shouldn't be like this. The clipboard already contains a perfectly structured table the moment you copy from Excel — tab-delimited text and an HTML rendering, both standard formats that the browser can read locally. The transformation into GitHub-flavored Markdown is mechanical: delimiters to pipes, a header separator row, escaping for the characters that collide. Mechanics are what tools are for.

So: paste here, get a table. This converter takes an Excel or Google Sheets selection — or an uploaded XLSX — and emits clean, aligned GitHub-flavored Markdown with pipes escaped, line breaks converted, alignment optional per column, and bold/links preserved when you want them. No account, no upload, no finger on the screen.

Paste becomes a table

The tool's input is the paste you already know how to make. Select a range in Excel — or Sheets, or Calc — press Ctrl+C, click the converter's paste area, press Ctrl+V. What arrives is the clipboard's plain-text layer: cells separated by tabs, rows by newlines, quoted fields preserved where the source wrapped them. The converter parses that into a grid, shows it back to you as a preview, and renders the Markdown live underneath.

For saved files rather than live selections, the XLSX upload path does the same thing one step earlier: it parses the workbook, lists the sheets, and lets you pick which range becomes the table. Legacy .xls workbooks are covered too, through the same reading engine as our XLS to CSV Converter.

The output box is the destination half. It holds the finished Markdown, aligned so the source reads like a table even before rendering — columns padded to equal width, the delimiter row matching. Alignment here is cosmetic; Markdown parsers trim cell whitespace, so the padding is for the humans reading the diff, which in a repository is at least half the audience. A copy button, a wrap-in-code-fences toggle for pasting into issue comments, and a compact mode that strips the padding round out the controls.

One paste, one table

  1. Copy the range

    In Excel or Google Sheets, select the range including the header row, and copy it normally. The clipboard does the rest — no special copy command needed.

  2. Paste into the converter

    Click the paste area and paste. The grid preview appears with your rows and columns exactly as the source had them, including empty cells.

  3. Choose your options

    Toggle rich formatting (bold and links) on or off, set per-column alignment, and decide whether numbers arrive as displayed ($1,250.00) or cleaned (1250).

  4. Read the Markdown

    The output box renders live. Pipes in your text are escaped, in-cell line breaks become <br>, and the delimiter row carries your alignment choices.

  5. Copy and ship

    One click copies the table. The code-fences toggle wraps it for contexts where raw Markdown, not rendered output, is what you're pasting into.

How GitHub-flavored tables are built

Markdown's core specification — CommonMark — has no tables at all. Tables arrived as a GitHub extension, used so heavily that GitHub formalized the syntax in the GitHub Flavored Markdown spec published in 2017. Every renderer in the ecosystem now supports that syntax: GitHub, GitLab, Bitbucket, VS Code's preview, most static-site generators, and every major documentation platform. It is the one table format that travels.

The grammar is three rows of ideas. A header row of cells. A delimiter row immediately after — hyphens per column, optionally wrapped in colons to declare alignment. Then any number of body rows. Cells separate with pipes; leading and trailing pipes are optional but universal, because they make the source readable. The delimiter row is also where the table's column count gets fixed: every row is padded or truncated to match it, which is how parsers stay lenient about ragged input.

| Plan  | Rows    | Price |
| :---- | :------ | ----: |
| Basic | 1,000   | $9    |
| Team  | 25,000  | $49   |
| Scale | 250,000 | $249  |

:--- left-aligns, :---: centers, ---: right-aligns, --- is no preference.
Rendered: three columns, numbers right-aligned, labels left.

Two rules in the spec do quiet, important work. Whitespace around cell content is trimmed, which is why the padded alignment above is free — the parser ignores it. And the number of columns in the delimiter row is authoritative, so a body row with too few cells gets empties appended and one with too many has its extras silently dropped. That second rule is why a stray unescaped pipe in row 17 doesn't error the render; it amputates the row's tail and keeps going. Silent truncation instead of a visible failure is a genuinely bad trade for documentation, and it's the specific reason escaping matters so much here.

Escaping: the three characters that collide

Markdown tables live inside Markdown, so cell content collides with the surrounding syntax in exactly three places. The pipe is the severe one — an unescaped pipe splits the cell and shifts everything after it one column left, and because of the truncation rule above, the damage is invisible in the render: the table looks fine with data missing. The converter escapes every content pipe as \| on output, which renders as a literal pipe everywhere GFM is understood.

Newlines end the row, so multi-line cell content — the classic Alt+Enter address block — becomes a <br> tag, the one piece of inline HTML the GFM table world agrees on. And leading/trailing whitespace in a cell vanishes on render, so meaningful indentation has to move into a code span if it matters. Everything else — asterisks, underscores, brackets — passes through as ordinary Markdown, meaning a cell reading *note* renders as italic note. When that's unwanted, the converter's literal-text mode wraps cell content in backticks or escapes the offenders; when it's wanted, leave it on and your spreadsheet's asterisk-footnotes become real italic markers in the README.

Worked example — a hostile row, converted correctly

Input

One Excel row, pasted (two cells):

Cell 1:  "USD|EUR basket"
Cell 2:  "Tier 1 (Q1 review)\nTier 2 (Q3 review)"  — an Alt+Enter line break inside the cell

Output

| USD\|EUR basket | Tier 1 (Q1 review)<br>Tier 2 (Q3 review) |

The pipe is escaped, so the first cell stays one cell. The line break became <br>, so the row stays one row. Pasted into GitHub, this renders exactly as the spreadsheet showed it — which is the entire specification this tool is trying to meet.

A pricing table, three ways

Here is the standard demo: the pricing table from the Tuesday scenario, pasted straight from Excel, with the converter's three output modes shown on the same input so the differences are visible side by side.

Worked example — paste from Excel, default output

Input

Copied range (4 rows × 3 cols), currency column formatted in Excel:

Plan | Rows | Price
Basic | 1,000 | $9
Team | 25,000 | $49
Scale | 250,000 | $249

Output

| Plan  | Rows    | Price |
| :---- | ------: | ----: |
| Basic |   1,000 |    $9 |
| Team  |  25,000 |   $49 |
| Scale | 250,000 |  $249 |

Default behavior: text left-aligned, numeric-looking columns right-aligned automatically, display values preserved exactly as Excel showed them.
Worked example — the same paste with number cleaning on

Input

Same clipboard, number-cleaning enabled, compact mode:

Output

| Plan | Rows | Price |
| --- | ---: | ---: |
| Basic | 1000 | 9 |
| Team | 25000 | 49 |
| Scale | 250000 | 249 |

Currency symbols and thousands separators stripped, padding removed. This is the output that survives a code review where someone diffs the numbers — and the one to choose when the table feeds a script.
Worked example — rich formatting preserved

Input

Same range, but "Scale" is bold in Excel and the Basic row's plan name is hyperlinked to /pricing/basic in the source sheet:

Output

| Plan  | Rows    | Price |
| :---- | ------: | ----: |
| [Basic](/pricing/basic) | 1,000 | $9 |
| Team  | 25,000 | $49 |
| **Scale** | 250,000 | $249 |

The HTML layer of the clipboard carried the formatting across; the converter translated it into Markdown emphasis and a link. Rendered on GitHub, the table is visually identical to the spreadsheet's formatting.

What Markdown tables cannot express

  • Merged cells. No colspan, no rowspan — a horizontal or vertical merge becomes the value in one cell and empties beside it. If the layout is the meaning, Markdown is the wrong destination.
  • Multi-line headers and sub-headers. One header row, one row of plain cells. Two-tier pricing headers ("Annual" spanning two columns) need restructuring into flat columns or a different format entirely.
  • Cell colors and conditional formatting. The GFM table has no styling vocabulary. Bold and italic survive; red-for-negative does not. A common compromise: append a marker column (▲/▼ or trend words) and let the reader's renderer theme do the rest.
  • Very wide tables. Horizontal scroll is renderer-dependent, and a 15-column table in a README is a readability problem no syntax can fix. Trimming to the columns a reader actually needs at decision time is documentation hygiene, and the converter's column toggles make it a checkbox rather than a re-export.
  • Formulas. Cells convert as their values, as with every clipboard path — the Markdown holds what the sheet displayed, not the logic. Nobody has ever wanted a VLOOKUP in a README, so this is less a limitation than a boundary.
  • Embedded objects and images in cells. Not part of the table grammar. Images can go in cells as standard Markdown image syntax if you supply URLs, but nothing in an XLSX carries one over automatically.
  • Numbers as text with leading zeros. A cell displaying 0071 pastes as 0071 and stays 0071 in Markdown — good. But a numeric cell with a 0000 format may paste via the HTML layer with formatting quirks; verify zero-padded ID columns in the preview before shipping.

Docs writers, data folks, README maintainers

The daily users are the people who maintain documentation adjacent to spreadsheets: engineers putting changelogs and config matrices into READMEs, technical writers moving spec tables from SME-authored workbooks into docs sites, product managers pasting comparison tables into PR descriptions and wikis. Their shared trait is that the spreadsheet is the source of truth and the Markdown is the publication format — the conversion happens repeatedly, every time the source updates, and automation tolerance for an erroring step is zero.

The second cohort is data people documenting datasets: variable dictionaries, field types, code mappings. These tables are wide, regular, and slightly too big for comfort — exactly the shape where hand-conversion introduces transposition errors that nobody notices until a downstream user reads the docs. A tool-assisted conversion with a visual preview is the difference between docs people trust and docs people verify.

And a long tail of once-a-monthers: the consultant formatting deliverable tables into a client wiki, the student moving lab data into a GitHub Pages report, the open-source maintainer transcribing a comparison spreadsheet into their project's README so the community stops asking which plan does what. For all of them the tool is the same thing: the Tuesday-afternoon tax, refunded.

Paste here versus the alternative routes

There are other ways to get a spreadsheet table into Markdown, and they're worth an honest comparison:

RouteSetupPreserves formattingHandles pipes/escapesBest for
This converter (paste)None — open the pageBold + links, optionallyAutomaticallyThe recurring copy-paste workflow
This converter (XLSX upload)NoneBold + links, optionallyAutomaticallySaved files, per-sheet picking
Hand-writing the tableNoneManuallyYou find out at render timeOne small table, once
Sheets add-ons / Excel pluginsInstall, permissions, accountVaries by add-onUsuallyHeavy repeat users living in one app
Pandoc / scriptsInstall a toolchainLimitedYes, with flagsAutomated pipelines, CI
CSV → Markdown convertersSave as CSV firstNo formattingUsuallyData-shaped tables; see our CSV tools
The realistic routes from spreadsheet to Markdown table.

The paste-first design isn't a gimmick; it's a recognition that the clipboard already solved half the problem. Excel and Sheets write two standard formats to it on every copy — plain tab-delimited text and an HTML table — so a browser tool that reads the paste locally gets fully structured input with zero conversion ceremony on your side. Uploading a whole workbook to get one 12-row table was always the disproportionate answer, and it's the reason upload-based converters never became the default habit for this job.

For the data-shaped variant of the task — tables with no formatting worth preserving — our CSV to HTML Table and JSON to Markdown Table converters cover the neighboring formats, and Markdown Table to JSON runs the reverse direction when what you need is to get data back out of a README.

The clipboard never leaves your machine

Everything in this tool is local. The paste is read by your browser from your clipboard event into the page's memory; the XLSX path parses the file with the browser's File API; the Markdown is generated by JavaScript in the tab. No paste is transmitted, no workbook is uploaded, no conversion history is kept on a server. There is no account to create and no free-tier counter — the page is the whole service.

For documentation work this matters in a specific way: the tables people convert are frequently internal — unreleased pricing, roadmap comparisons, vendor evaluations, security-relevant configuration matrices. A converter that phones the clipboard home would be a data-leak vector wearing a helpful face. This one can't, structurally: open the dev-tools network panel during a conversion and watch nothing leave. It also works fully offline once loaded, for the same reason.

Excel-to-Markdown questions, answered

Why does my table break when the cell text contains a pipe character?

In GitHub-flavored Markdown, the pipe is the cell delimiter, so a literal pipe inside your text splits one cell into two. The fix is escaping it with a backslash: A\|B renders as A|B. The converter handles this automatically — every pipe inside cell content is escaped on output, so pasted data with pipes survives intact.

Why do my numbers come out as $1,250.00 instead of 1250?

When you copy from Excel, the clipboard carries the displayed value, not the stored one — a currency-formatted cell copies as the string you see. The converter has a number-cleaning option that strips currency symbols, thousands separators, and percentage signs on the way into Markdown, if you want raw numerals instead of display text. Both are legitimate choices; the option exists because READMEs usually want one and pricing docs usually want the other.

Does the converter preserve bold text and links from my spreadsheet?

Yes, optionally. Excel puts an HTML rendering on the clipboard alongside the plain text, and the converter can read that layer — bold becomes bold, and hyperlinks become text. Toggle rich formatting off when you want the plain values only, which is the right setting for data tables destined for code review.

What happens to line breaks inside a cell (Alt+Enter in Excel)?

They become <br> tags. GitHub-flavored Markdown tables cannot contain raw line breaks — a newline would end the row — so the HTML break tag is the standard, universally rendered substitute. Multi-line addresses and stacked notes convert cleanly this way.

Can the converter handle merged cells?

No, because Markdown tables can't either — there is no colspan or rowspan in the GFM table syntax. A merged cell in Excel exports as its value in the top-left position of the merge and empty cells elsewhere. For layouts that depend on merges, a screenshot or an HTML table is the honest destination rather than Markdown.

Can I control column alignment in the output?

Yes. Each column has an align setting — left, center, right, or none — which the converter expresses in the delimiter row: :--- for left, :---: for center, ---: for right, and a bare --- for no preference. Numeric columns default to right alignment, text to left, and both defaults are overridable per column.

How many rows can it convert?

Technically thousands — the conversion is instant in-browser and GitHub renders large tables. Practically, tables beyond a hundred-plus rows stop being readable documentation and become a data artifact, at which point linking to a CSV or spreadsheet serves readers better. The tool handles the full range either way; judgment about where documentation ends is yours.

Does it work with Google Sheets too, or only Excel?

Both, plus LibreOffice Calc and anything else that puts a standard clipboard table on the wire. Sheets copies the same two layers — plain tab-delimited text and HTML — so the paste-in path is identical. The XLSX file-upload path covers saved workbooks from any of the three.

Next stops on the conversion line

Tables flow in both directions around here. When the task is the reverse — extracting data back out of a README — Markdown Table to JSON parses GFM tables into structured records. When the destination is a web page rather than a repo, CSV to HTML Table produces styled HTML with sorting, and JSON to Markdown Table covers the API-shaped inputs. And when the source is an old binary workbook, XLS to CSV Converter normalizes it before anything else touches it.

Specs cited

Sources and further reading

We cite primary sources (standards bodies, government agencies, official documentation) wherever they exist so you can verify every number on this page yourself.