XLSX translation files

A spreadsheet is not a localization format. It is also what a large share of translation work actually arrives as, so it is worth handling properly instead of pretending it does not happen.

The shape that works

One row per string, one column for the source, one column for the target, and any number of other columns for identifiers, comments, context, character limits or screenshots. That is the whole contract.

A            B                                   C                    D
ID           Source                              Target (de-DE)       Comment
1            Save your work before you close.    Speichern Sie …      UI, keep short
2            Deleted {0} files.                  {0} Dateien …        {0} is a count
3            The upload failed: %s               Der Upload …         %s is a raw error

Rows are addressed by their real spreadsheet row number, so segment three above is row four of the sheet. That matters more than it sounds: matching by row number rather than by position in a list means a filtered or re-sorted view in the editor cannot write a translation into the wrong row.

How the columns are found

The first pass reads the header row and looks for recognizable column names. The vocabulary covers English, German, French, Spanish, Russian and Chinese:

Source column source, quelltext, quelle, origen, fuente, источник, 源文, 原文
Target column target, zieltext, ziel, cible, destino, meta, перевод, 目标, 译文

Headers are normalized before matching: a trailing bracketed group and trailing punctuation are stripped, so Target (de-DE): matches target. The language tag inside those brackets is not thrown away — it becomes the target language of the document, because a workbook carries no language metadata anywhere else.

The match is exact on the normalized text, never a substring. That is a deliberate choice with a specific failure in mind: Meta and Ziel are legitimate target headers and are short enough that substring matching would fire on Metadata or Zielgruppe and quietly send every translation into a column of notes. When a header is not recognized, the column mapping dialog is the answer, not a cleverer guess.

Workbooks with several sheets

Header keywords beat position across the entire workbook. The header pass runs over every sheet before any positional guess is attempted, which is what keeps a typical delivery honest: a first sheet named "Info" or "Instructions" with two columns of prose would win a per-sheet race, but only the second sheet has real source and target headers, and that is the one that gets opened. Every other sheet is left alone completely.

When there are no headers

A workbook with no recognizable headers falls back to position: the first two columns that are mostly text. "Mostly" is at least sixty per cent strings among the non-empty cells, because a real bilingual export often has a stray number in a source column — a version string, a lone year — and demanding purity there would reject the whole sheet.

Deciding whether the first row is a header or data is the risky part, so the fallback is deliberately reluctant. A header row is assumed only when all three of these hold: both mapped cells in the first row are non-empty strings, neither of those values reappears further down its own column, and at least one mapped column contains a non-string value somewhere below. The third condition is the one that earns its keep. Two all-text columns of translations look exactly like labels above data to any simpler heuristic, and guessing wrong there silently deletes the first segment. Keeping a stray label row as a segment is visible and fixable in two seconds; losing a row of somebody's translation is neither.

Everything detection decides can be overridden before you start work: the sheet, the source column, the target column and whether the first row is a header. The overrides are applied field by field, so correcting the target column does not throw away the correct sheet.

What survives an export

Spreadsheets are the one family here that is exempt from byte-identical round trips. A workbook is a zip archive of XML parts, and re-emitting it will not reproduce the same bytes. What is guaranteed instead is structural: the original workbook is loaded and re-emitted, and every part that was not touched comes back as it was.

  • Cell styles, fonts, fills, borders and number formats.
  • Column widths, row heights, frozen panes and autofilters.
  • Every sheet other than the one being edited.
  • Every column of the edited sheet other than the target column.
  • Row order and row count. No row is added, removed or moved.
  • Cell types. A number stays a number, a date stays a date.

Only mapped target cells are written, and only the ones whose text actually changed. Clearing a target sets the cell to empty rather than deleting it, which keeps the cell's formatting — a translator emptying a row does not expect the row's styling to fall apart. If nothing changed at all, the export hands back the original bytes untouched, so an accidental open-and-export is a no-op.

The detection runs again from the original bytes at export time rather than trusting a mapping carried in memory. That makes an export after a browser restart identical to an export in the session where the file was opened, and it removes the class of bug where a restored session writes into a different column than the one you saw on screen.

Practical advice

A few things make a spreadsheet job go smoothly, and most of them are decisions the person who builds the file makes before anyone translates a word.

  • Keep a stable identifier column. When the file comes back and has to be merged into a resource file, row order is not an identifier and neither is the source text.
  • Put the language tag in the header, as Target (de-DE). It costs nothing and it is the only place a workbook can say what language it is in.
  • Do not merge cells in the source or target columns. A merged range has one value and several row numbers, and nothing downstream handles that well.
  • Avoid formulas in the target column. An edit writes literal text into the cell, which replaces the formula — usually what you want, but a surprise if the column was computing something.
  • Sort and filter before you send the file, not after. Sorting a delivered file breaks the link to whatever the developer merges it against.
  • Placeholders are plain text in a cell, with no tag layer to protect them. The QA checks still compare placeholders between source and target, so a missing %s is caught, but nothing stops you typing over one — treat them with the care an inline tag would normally enforce.
  • Line breaks inside a cell are fine and survive the round trip. Trailing spaces survive too, which is worth remembering when a QA check flags one.

Related formats

CSV and TSV use the same column-mapping logic with a different set of hazards, mostly around delimiters and encodings. If your source material is really XLIFF, the XLIFF 1.2 and XLIFF 2.0 pages describe what a spreadsheet round trip is giving up: states, inline tags, comments and match rates.

Going the other way: convert an XLIFF file to Excel.