CSV Viewer

Open a CSV, TSV or Excel file — or paste raw text — and read it as a clean, sortable, filterable table.

The file is parsed locally in your browser with SheetJS. Only the parser library comes from a CDN; your data stays.

Drop a CSV / TSV / XLSX file or click to browse

Delimiter
Rows per page
—

Load or paste some data to see the grid.

How It Works

Parsing is done by SheetJS, the reference open-source spreadsheet reader, running locally in your browser. Text input (pasted data or .csv/.tsv files) goes through its delimiter parser — auto mode lets the parser infer the separator from the first line, manual mode forces a specific one. Binary files (.xlsx, .xls, .ods) go through the full workbook reader and the active sheet is flattened to a plain array of arrays, so every source ends up as one uniform grid before anything is rendered.

Header row and quoting
With the header toggle on, row 1 names the columns and gets pinned in the sticky top row; with it off the columns are numbered and row 1 stays data. The parser honours RFC 4180 quoting: commas and newlines inside double-quoted fields stay inside the cell, and doubled quotes escape a literal quote.
Sorting is stable and numeric-aware
Clicking a header sorts ascending, then descending. Cells that parse as numbers compare by value — so 9 sorts before 10 — while everything else compares as text, case-insensitively. Rows with equal keys keep their original relative order because the sort decorates rows with their input index and breaks ties with it; JavaScript's own sort is also stable in modern engines.
Why pagination matters
A grid is made of real DOM nodes: 50k rows × 10 columns is half a million elements, which stalls layout and makes filtering and sorting crawl. Rendering only the current page keeps every interaction instant, and even the All view caps at 5,000 rendered rows — the file is still fully parsed, you simply see a window into it.

Frequently Asked Questions

Do Excel files render too?

Yes. Drop an .xlsx or .xls workbook and the active sheet — the one that was open when the file was saved, or the first if none is marked — is flattened into a grid. Other sheets are not shown, and formulas arrive as their last calculated values, since that is what the file stores for other applications.

Why do dates look different than in my spreadsheet?

Because dates are rendered from their raw stored values, not from your chosen display format. A date cell may surface as an ISO-style string like 2026-01-15T00:00:00, or as the serial number SheetJS did not manage to recognize, depending on how the file was written. The viewer is deliberately honest: what you see is what the file holds.

How does the delimiter auto-detect work?

For text pastes and .csv files, Auto lets the parser decide from the first line's character mix; .tsv files start with tabs. If a file uses a semicolon — common in locales where the comma is a decimal separator — switch to it manually in the Delimiter select and the table re-parses instantly.

What size file is comfortable?

Parsing tens of thousands of rows is routine, but the grid is the limit: rendering all 100k rows at once would freeze the tab, which is why All view caps at 5,000 rendered rows and the default page size is 50. For a quick look at a very large export, keep pagination on rather than forcing All.

Is anything uploaded to a server?

No. The file is read with FileReader and parsed locally by the SheetJS library; your data never leaves the tab. The only network request is the one-time fetch of that public parsing library from the SheetJS CDN — your file's contents are never sent anywhere.