Excel Paste to JSON/Markdown
Turn a range copied from Excel, Google Sheets or Numbers into JSON or a Markdown table — entirely on this device.
Data keeps every pasted row and names the columns col1, col2, … Off keeps ZIP codes, IDs and leading zeros as text.
Paste the range with the paste shortcut. The clipboard's HTML flavor is read once, in this tab, only to flatten merged cells — it is never stored.
Drop a .tsv, .txt or .csv file here and it is read as text in this tab — nothing is uploaded.
Press ? for shortcuts
Do it offline:$ pbpaste | mlr --itsv --ojson cat
How to use it
- Copy a range in Excel, Google Sheets or Numbers and paste it into the input pane — a dropped .tsv, .txt or .csv file is read as text instead.
- Pick the output tab: JSON, or a Markdown table for a README or a pull request.
- Say whether the first pasted row is a header, then set the JSON details — objects or arrays, empty cells as an empty string or null, indented or compact.
- Copy the result, download it, or share the state as a link; Clear and Sample are one undo away.
Select cells in a spreadsheet, press copy, paste here: the range arrives as tab-separated text and leaves as JSON or a GitHub-ready Markdown table. Leading zeros stay text, a comma inside a cell stays data, and in-cell line breaks become <br>. Nothing is uploaded — the clipboard never leaves this device.
How it works
One copy out of a spreadsheet puts the same selection on the clipboard several times over, in different flavors. This page reads the plain-text one, which every spreadsheet writes as tab-separated text: columns split on tabs, rows on line breaks, and any cell holding a tab, a line break or a quote arrives wrapped in double quotes with its inner quotes doubled. So a comma is ordinary data here, and the reader has to understand quoting.
The markup flavor of the same copy carries the sheet's table structure. It is sniffed, never used for values: the scan looks for a row or column span above one so a flattened merge can be reported, and gives up after 256 KB. Only a real paste hands that flavor over, and it is held in memory rather than stored.
Examples
city population notes
Osaka 2,691,185 port, inland
Lyon 522,250 second ring[
{
"city": "Osaka",
"population": "2,691,185",
"notes": "port, inland"
},
{
"city": "Lyon",
"population": "522,250",
"notes": "second ring"
}
]Four commas across the two rows and none of them splits a cell: the flavor being read is tab-separated. Keys come out in the order the columns were selected, and values stay strings by default.
owner next step
Ada "rotate the key
file the ticket"
Noor hand over| owner | next step |
| ----- | --------------------------------- |
| Ada | rotate the key<br>file the ticket |
| Noor | hand over |Ada's cell was copied with a line break inside it, so the clipboard wrapped that cell in quotes. A pipe table has nowhere to put the break, and the chip counts it: 1 multi-line cell kept as <br>.
sku units
A-0007 12
00042 3[{"sku":"A-0007","units":12},{"sku":"00042","units":3}]Detect types is off by default. Switched on here it turns the units column into real JSON numbers, then stops at 00042 — row 2, column "sku": "00042" kept as a string — a leading zero would be lost as a number.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
Merged cells flatten to their first cell
A merged range cannot exist in either output: its value lands in the first cell and the cells it spanned come through empty. Detecting that takes the markup flavor, so the chip appears only after a real paste.
A reopened link cannot show the merge chip
Shared links and the session buffer carry the pasted text and nothing else, so a reopened table is identical but the merge chip is gone. Paste again to get it back.
Where this page stops: 10,000 rows, 100 columns, 10 MB
Past any of the three, conversion refuses and prints the limit it hit. Clipboard-sized ceilings: a whole exported table belongs in the CSV to JSON converter, which takes 100 MB.
Workbook files are a different tool
Nothing here opens an .xlsx, .xls or .ods — this page sees only the text a copy left on the clipboard. For a saved workbook use the CSV to Excel converter.
A line break inside a cell is spelled <br> in JSON too
One policy covers both targets: the break becomes a <br> tag before either writer runs, so the JSON string holds those four characters.
Common errors
the table is 2 rows × 101 columns — this tool's grid is limited to 10,000 rows × 100 columns- A range that wide is nearly always a whole sheet rather than a selection. The refusal names both ceilings beside the shape it measured, and your input stays put.
Input is larger than the 10 MB limit for this tool.- Size is checked before any splitting starts. Export the sheet to a file and convert that instead.
1 ragged row padded with empty cells to 3 columns — rows 2- A copied selection is a rectangle, so a short row usually means the text was typed or edited after the copy. Padding keeps the widths equal; the warning numbers the rows it touched.
duplicate header "date" — renamed to "date_2" so no column is lost- Two columns sharing a name would collapse into one key, and one value would vanish without a trace. The rename keeps both, with a stable suffix.
FAQ
Why does pasting from Excel give tabs instead of commas?
Because tab-separated text is what a spreadsheet writes to the plain-text clipboard flavor; the comma layout appears only when you save a file as CSV. So a cell containing a comma needs no quoting and arrives whole.
Can I paste a range that has no header row?
Yes — set the header control to generate and every pasted row stays data. The columns then get positional keys: col1, col2 and so on, left to right. The chip that reports it names the same keys, so nothing has to be translated by hand afterwards.
Do Google Sheets and Numbers paste the same way as Excel?
Closely enough that one reader covers all three: each writes the selection as tab-separated text and quotes any cell holding a tab, a quote or a break. Numbers and some Windows exports add a byte-order mark, which is stripped and reported.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Convert the pasted range again right now.
- ⌘/Ctrl + S
- Download the output — .json or .md, per the active tab.
- ⌘/Ctrl + C
- Copy the output while nothing is selected.
- ⌘/Ctrl + Shift + C
- Copy the output even over a selection.
- t
- Move to the next theme.
- ? or ⌘/Ctrl + /
- Open the shortcut help overlay.
- Esc
- Close the topmost overlay; panes stay put.