Saltar al contenido principal

Merge CSV Files

This merger combines several CSV files into one, aligning columns by header name rather than position: the output header is the union of every file's columns, and rows fill what they have, blank where they do not. Parsing and writing happen in your browser; the files are never uploaded.

Solo local

La interfaz de esta herramienta está en inglés.

La guía de abajo solo está disponible en inglés.

Merge CSV Files explained

Two exports of the same kind of record almost never agree on columns — one has name and email, the other name and company. Stacking them is how wrong files get made: rows land under whichever header happens to be above them, and a column named email silently collects somebody else's company values. The fix is to union columns by name and remap every row through its own file's header.

That is what this merger does. The output header is the ordered union — the first file's columns in their order, then each new column the moment some file shows it. Every row is written against that union, taking values from the columns its own file has, leaving the rest blank. Output is RFC 4180: commas, fields quoted only when required, CRLF row endings.

Multiple files stay local. Attach them with the file picker — the browser's file API reads them into memory in this tab — or paste them separated by a line containing only ---. Nothing is sent anywhere; there is no upload step because none exists.

The quoting, CRLF and escaping rules the merged output obeys are written up in plain terms in the site's RFC 4180 guide — worth five minutes before you build a pipeline on CSV.

Once the files are one table, the usual next step is records a script can consume, and the CSV to JSON converter makes that a one-click follow-up.

Union by name, not by position

The distinction sounds academic until it saves a file. Suppose file one has columns name, email and file two has name, company. The union header is name, email, company — file one's columns first, then the new column. Ada's row fills email; Grace's fills company; each leaves the other blank. The worked example below shows exactly this pair.

Because the mapping runs through each file's own header, column order inside a file is irrelevant: file two could arrive as company, name and its values would still land correctly — precisely what positional stacking gets wrong, and why a merger that assumes identical headers is a trap.

Ragged files, BOMs and other real-world wrinkles

Real exports are ragged, and the merger absorbs the common cases rather than bouncing them:

  • A UTF-8 BOM at the start of a file is stripped — otherwise an Excel export grows an invisible first column nobody can match.
  • Blank lines are skipped, and an empty file is ignored, not fatal.
  • Rows missing trailing cells become blanks — ragged right edges are normalised, not errors.
  • Parse failures are reported per file and per line — file 2: unterminated quoted field, line 4 — so the problem file identifies itself.
  • A header that repeats a name within one file is read at its first position only; de-duplicate such headers if the second copy carries data.

What the output looks like — and what it refuses to do

The output is one CSV document: a single header row, then every file's rows in order. Row endings are CRLF with a trailing CRLF, per RFC 4180, and fields are quoted only when necessary: a comma, a quote (doubled, as the standard requires) or a line break inside, or leading or trailing whitespace a spreadsheet would otherwise strip.

Values pass through as text — a customer number 007 stays 007 — and nothing is deduplicated or reordered. Two identical rows in are two rows out: collapsing them requires deciding what makes two rows the same, and that call is yours, not the tool's.

Frequently asked questions

Do the CSV files I attach get uploaded?

No. Attached files are read with the browser's file API into strings inside this tab, merged there, written back out — nothing leaves the device. The page is served with connect-src 'self', so a fetch to another origin is refused by the browser itself, and the Network panel shows no traffic while a merge runs. Payroll exports staying local is the point.

What if my files have different columns, or the same columns in a different order?

That is the case the tool exists for. Columns are unioned by name, every row is remapped through its own file's header, so column order inside any file is irrelevant. Rows simply leave blank the columns their file never had.

Are duplicate rows removed?

No. Merging is structural alignment; deduplication is a separate decision about identity — every column, a key, case-insensitively? — and guessing wrong deletes real data. Identical rows pass through untouched; apply your own rule afterwards if you need it.

Which CSV dialects does the parser accept?

Comma-delimited RFC 4180: quoted fields containing commas, quotes and line breaks, doubled quotes, and either CRLF or LF input endings. Semicolon-delimited exports — the European Excel default — parse as a single wide column, so re-save those with commas first. Output is always comma-delimited with CRLF endings.

How are ragged rows handled?

A row shorter than its file's header contributes blanks to the missing columns; a row longer has unnameable leftovers — cells with no column name — which are ignored. Repeated header names within one file are read at the first occurrence. Quiet handling is reserved for these; malformed syntax gets a per-file, per-line error.

Is there a size limit for the files?

The practical limit is the browser tab's memory. Each file is parsed by the site's main-thread CSV engine, which refuses inputs above 8 MB with a clear message rather than freezing the page — the same documented limit the site's other CSV tools apply. For typical exports that is tens of thousands of rows per file.