CSV Editor & Viewer
Open a CSV in a grid, edit cells, rows and columns, then export it with your delimiter and quoting intact — entirely on this device.
Quoting, line endings and the BOM apply to what you copy, download and share — the grid is unaffected.
The table appears here once there is CSV to read.
Press ? for shortcuts · Drop a .csv, .tsv or .txt file anywhere in this pane.
Do it offline:$ column -s, -t data.csv | less -S
How to use it
- Paste the text into the left pane, drop a .csv, .tsv or .txt file on it, or load the sample. The dropped file is read here and goes nowhere else. Under 64 KB the grid follows your typing; past 256 KB the work moves to a background thread and ⌘/Ctrl + Enter starts it.
- Read both pane headers first. The left one names the delimiter that was read, and clicking that badge pins it so it stops changing with the text; the right one counts the rows and columns you got. A different delimiter — comma, semicolon, tab, pipe, or up to eight characters of your own — comes from the Delimiter control above the panes.
- Work in the grid. Arrow keys move the focused cell, Enter or F2 opens it for typing, Escape abandons the change, and the menu on a row header adds or deletes that row; its column items name the column they act on — the last one you visited. ⌘/Ctrl + Z steps back through everything you have changed.
- Copy the table, download it as a .csv file, or press Share to fold the current text and every option into a link. Export writes the rows in the order you are looking at, so a sorted or filtered view is the file you receive.
Paste a CSV or drop the file: it opens as a grid you can work in — retype a cell, insert or delete a row, drop a column, rename a header. Only the rows on screen are drawn, so a file with hundreds of thousands of rows scrolls without stalling, and Export hands back the whole table with the delimiter and quoting you chose.
How it works
Reading the text produces one table in memory: the column names, the data rows squared to a single width, the delimiter that was used, and the census the pane header prints. Nothing else is kept — there is no second copy of your document behind the grid, so what you scroll and what you export are the same rows. Cells arrive as text and stay text: the grid has no notion of a number, a date or a formula.
The grid draws a window, not a file. Row height is fixed, so the number of rows that fit is arithmetic: the scroll position picks a first row, a few extra rows above and below absorb fast scrolling, and beyond two hundred rows only that slice exists in the page. A quarter of a million rows therefore costs about what fifty cost, and the pane keeps its size in every state, so nothing jumps as a table loads.
Editing is a set of small operations over that table, each addressed by position: set the cell at row 4, column 2; insert a row at 9; insert a column at 1; delete column 3; rename the header at column 0. Position rather than name, because a real export can carry two columns called email. Each operation returns a fresh table plus a plain-language note for anything it had to adjust, and one step of undo covers cell and structural changes alike.
Export walks the finished table through a single writer. Fields are wrapped in quotes only where leaving them bare would change what a reader sees, following RFC 4180, and your choices of delimiter, line ending, quote-everything and byte-order mark are applied on the way out. Sorting a column and typing in the filter box change the view, never the stored rows, and the export follows the view; the share link carries the current text, so reopening it lands on the document you were editing rather than the one you pasted.
Examples
sku,qty,note
KB-701,2,
MS-220,1,backorder
sku,qty,note
KB-701,5,
MS-220,1,backorderTyping 5 over the qty of the first row rewrites that one cell. The empty note on the same row is still an empty field, the second row is untouched, and the export ends without a final line break — the writer adds a separator between rows, not after the last one.
item,detail
"Widget, large","says ""hi""
line two"
item,detail
"Widget, extra large","says ""hi""
line two"An edge case worth trusting: one cell holds a comma, the next holds a pair of quote marks and a line break, and the grid shows two columns rather than four. Editing the first cell leaves the second exactly as it arrived — same characters, same internal break — because the round trip re-derives the wrapping instead of copying it.
id,name,city
001,Ada
002,Lin,Oslo,
id,name,city,col4
001,Ada,,
002,Lin,Oslo,Three lines of unequal width open as a rectangle. The header lists three names but a row carries four fields, so the extra column is given the placeholder name col4 and counted; the short row gains empty cells. The id 001 keeps its zero, and the warning above the grid says which rows were squared up.
email,email,id
a@x.test,b@x.test,0091
email,id
a@x.test,0091Two columns named email arrive; the second is shown as email_2 so neither is lost, and deleting column 1 removes the one you clicked rather than the first match by name. The remaining pair keeps its original order and the leading zeros of 0091 survive the edit.
id,city
001,Oslo
002,Lyon
id,name,city
001,Ada,Oslo
002,Lin,LyonA column inserted at position 1 lands between id and city, taking its header and a value per row; city shifts right without being rewritten. Inserting past the last column appends instead, and the census moves from two columns to three.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
Sorting and filtering change the view, not the rows
Clicking a column header reorders what you see and cycles through ascending, descending and back to the stored order; the filter box hides rows that do not match. Neither touches the table itself. Export deliberately follows the view, so the file you download is the arrangement in front of you — and the pane says so before you press it.
Columns are held by position, so duplicate headers are safe
Exports out of reporting tools regularly repeat a column name. The grid labels the repeat with a numeric suffix for reading, but every edit names a column by its index, so deleting or renaming one of a pair never guesses which you meant. Renaming a header changes the label alone; the cells below it are not rewritten.
A trailing separator is a real column, and short rows are filled
A line ending in the delimiter carries one more empty field, which the grid shows as a final column rather than dropping. When rows disagree about width the widest wins: narrower rows gain empty cells, a warning lists up to twenty of the rows involved with an honest count of any tail, and an unnamed column is labelled col3, col4 and so on.
Cells are text and stay text
A leading zero, a nineteen-digit account number, 1E5 and a value beginning with an equals sign are all carried through the grid and back out as the characters you gave — nothing here converts them to a number or a formula, which is not true of opening the same file in a spreadsheet.
A line break inside a cell stays inside that cell
A field may legally contain a real newline, and the grid keeps it in one cell instead of inventing a row: the cell shows the break and the row count does not change. Editing a neighbouring cell leaves that field intact, and the export re-wraps it so the next reader sees the same single field.
Large files: a background thread, a window of rows, and a hard cap
Below 64 KB the table is re-read as you type. Above 256 KB reading and writing move to a worker thread so the page stays responsive, and only the visible slice of rows is ever drawn. Past 100 MB the input is declined whole rather than loaded in part, because editing a fraction and exporting it would quietly discard the rest.
Impossible edits are reported, not refused
Ask to edit row 900 of a 12-row table and the change lands on the last row with a note saying so; ask to edit before anything has been pasted and the request is ignored with a note rather than an error. Emoji are carried and edited whole, never split down the middle.
Common errors
Input is larger than the 100 MB limit for this tool. For bigger files use the CLI: column -s, -t data.csv | less -S- The cap is on the whole input, and it is refused rather than trimmed: a grid holding the first hundred megabytes would export a truncated file that looks complete. Your paste stays where it is, and the command in the banner aligns the columns locally so you can scroll them, with no more network traffic than this page uses.
Row 2: quoted field opened at column 8 never closes — this usually breaks every following row; close the quote, or write quotes inside a field as "".- One unmatched quote mark turns everything after it into a single enormous field, which is why the row and column of the opening quote are named instead of a vague parse failure. Close the quote in the left pane, or double it if the character belongs to the data.
Delimiter is 9 characters — this tool accepts up to 8.- The custom-delimiter box takes between one and eight characters, and rejects any that contain a quote mark or a line break, since those already mean something between fields. A rejected delimiter changes nothing: the grid keeps the table you had.
FAQ
How big a CSV can this page open?
Up to 100 MB of text, and the row count is not the limiting factor: only the rows you can see are drawn, so scrolling a table of several hundred thousand rows behaves like scrolling a short one. Reading and writing a file that size happen on a background thread so the tab keeps responding.
If I sort or filter, what ends up in the exported file?
What you are looking at. Sorting and filtering are treated as a lens over the stored rows, and both Copy and Download write the rows in the order and selection currently shown. Clearing the filter and cycling the sort back to its third state returns the original arrangement.
Can I add and remove rows and columns, or only retype cells?
Both. The menu on a row header inserts a row above or below and deletes a row; its other items name the column they act on, then insert a column after it, delete it or rename its header. Each of those operations is applied by position and can be stepped back with undo.
What happens to a file I drop on the left pane?
It is read by this browser tab and used to fill that pane — no request carries it anywhere, which you can watch in the network panel while you work. A drop that misses the pane is swallowed rather than followed, so a near miss cannot navigate away from unsaved work. A share link keeps the document in the part of the URL after the hash, and browsers never transmit that part to a server.
Do awkward cells survive being edited here?
Yes: a field containing the separator, a quote mark, a line break or leading and trailing spaces comes out of the round trip with the same characters it went in with — spaces included, since they belong to the field and are never trimmed.
Is there a way back if I delete the wrong column?
One step of history covers every cell and structural change, so ⌘/Ctrl + Z restores the column with its values and ⌘/Ctrl + Shift + Z reapplies the deletion.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Read the current text into the grid now — the way to run it once the input passes 256 KB, wherever the cursor sits.
- ⌘/Ctrl + S
- Download the table as a .csv file with the delimiter, line ending and quoting currently selected, instead of the browser's save dialog.
- ⌘/Ctrl + C
- With no text selected, copy the whole table as CSV; a real selection copies itself, and a cell open for editing copies its own contents.
- ⌘/Ctrl + Shift + C
- Copy the whole table as CSV regardless of focus or selection.
- ⌘/Ctrl + Z
- Step back one change — a retyped cell, an inserted or deleted row, an added, dropped or renamed column. Inside the text pane the browser's own undo takes over instead.
- ⌘/Ctrl + Shift + Z
- Reapply the change you just stepped back from.
- ? or ⌘/Ctrl + /
- Open keyboard help, which lists the grid keys as well: arrows to move between cells, Enter or F2 to edit one, Esc to cancel, Home and End for the first or last column, PageUp and PageDown by screenful, Tab to leave the grid.