React CSV Importer: Spalten zuordnen, Zeilen korrigieren

Die Anfrage klingt einfach: Ein Kunde hat 3.000 Kontakte in einer Tabelle und will sie in deiner App haben. Ein schlichtes File Input und ein Parser bringen dich bis zur Hälfte. Beim Rest geben die Leute auf: Ihre Spalten heißen „E-mail“ statt „Email“, in Zeile 412 steht eine Telefonnummer mit zwei Ziffern, und die Fehlermeldung sagt „Import failed“, ohne Zeilennummer. Ein guter React CSV Importer führt auch Leute ohne Technikwissen durch vier Schritte (hochladen, Spalten zuordnen, Zeilen korrigieren, ausführen) und schickt sie nie zurück in Excel, um es noch einmal zu versuchen. Dieses Tutorial baut einen mit der Komponente CSV Import von Wingo UI, der Bibliothek, die wir bauen. Wir sind also nicht neutral; externe Fakten sind mit ihren Quellen verlinkt.
Was muss ein React CSV Importer können?
Vier Schritte, und jeder beseitigt einen Grund, dem Support zu schreiben:
- Hochladen. Nimm CSV-, TSV- und Excel-Dateien per Drag and Drop, Klick oder Einfügen an und zeig, was gelesen wurde: Zeilen, Spalten, Trennzeichen, Kodierung, Tabellenblatt.
- Spalten zuordnen. Verbinde jedes deiner Felder mit einer Spalte der Datei, vorab über den Namen zugeordnet; über ein Select lässt sich jedes Paar ändern.
- Prüfen. Prüf jede Zeile gegen die Feldtypen, zeig die fehlerhaften Zellen und lass die Leute sie direkt korrigieren oder die Zeile überspringen.
- Importieren. Schick die gültigen Zeilen mit Fortschrittsbalken und Abbrechen-Button und melde danach, was angelegt, aktualisiert, übersprungen und fehlgeschlagen ist. Die fehlgeschlagenen Zeilen gibt es als Datei zum Herunterladen.
Der schnelle Weg zum CSV Import in React ist ein File Input, ein Parser und ein console.log der Zeilen. Das deckt Schritt eins ab. Das Open-Source-Paket react-csv-importer (opens in a new tab) (MIT, auf Basis von Papa Parse) geht weiter: Upload, eine Vorschau der Rohdaten und Spaltenzuordnung per Drag and Drop. Zur Validierung der Zeilen steht in der README aber nichts, und das Repository ist seit dem 5. Januar 2024 archiviert (geprüft im Oktober 2026). Schritt drei ist der, der das Support-Ticket erspart, deshalb bekommt er unten den meisten Platz.
Wie installiere und rendere ich den Import-Wizard?
Installier ihn mit einem CLI-Befehl und render dann CsvImport mit zwei Props: den Feldern, die du importierst, und einer Funktion, die die Zeilen speichert.
Der Befehl holt auch alles, woraus der Wizard gebaut ist: die Dropzone von File Upload, die Helfer aus Spreadsheet, die die Datei lesen, die Schritte aus Form Wizard und die Tabelle. onImport muss ein Promise auf ein ImportResult ({ created, updated, skipped, failed? }) zurückgeben. Für den Endpoint unten nehmen wir also an, dass er genau diese Form zurückgibt.
Probier unten den ganzen Ablauf aus. Die Beispieldatei ist ein Kundenexport, in dem ein paar Probleme versteckt sind.
$ npx wingo-ui@latest add csv-importWie beschreibe ich die Felder?
Das fields-Array steuert jeden Schritt: die Zeilen der Zuordnung, die Vorlage zum Herunterladen, die Validatoren und die Form der Zeilen, die du bekommst. Jedes ImportField hat eine id, ein label und optionale Regeln:
type:text,number,currency,date,email,phone,boolean,select, dazucui,ibanundcnpfür rumänische Steuernummern, Bankkonten und Personennummern.required: Die Zuordnung sperrt „Continue“, bis das Feld eine Spalte hat, und leere Zellen werden zu Fehlern.aliases: andere Überschriften, die dasselbe Feld meinen. In echten Exporten steht „E-mail“, „Mobile“ oder „Company name“.optionsfür Selects, mitkeywordsfür die Schreibweisen, die Leute wirklich tippen.validate(value, row)für deine eigene Regel nach der Typprüfung; gibt eine Meldung odernullzurück.transform(value)für den Wert, der anonImportgeht.examplefür die Vorlage.
onImport bekommt dann typisierte Werte: Zahlen für Beträge, ISO-Daten, Telefonnummern im Format E.164 und die Werte der Optionen statt dessen, was in der Tabelle stand.
Wie liest der Upload-Schritt CSV- und Excel-Dateien?
Der Upload-Schritt ist ein React CSV Upload in zwei Teilen. Die Dropzone von File Upload kümmert sich um die Eingabe: Drag and Drop, Klick, Enter oder Leertaste, Einfügen und auf dem Handy die native Dateiauswahl. Die Prop accept steht standardmäßig auf .csv,.tsv,.txt,.xlsx und maxFileSize auf 20 MB.
Das Lesen der Datei übernimmt readSpreadsheet aus den Spreadsheet-Helfern. Es erkennt, ob Komma, Semikolon, Tab oder Pipe das Trennzeichen ist. Das ist wichtig, weil Excel mit vielen europäischen Ländereinstellungen CSV mit Semikolon speichert. Es liest UTF-16, wenn die Datei mit einer UTF-16-Byte-Order-Mark beginnt, dekodiert den Rest als UTF-8 und fällt auf Windows-1250 zurück, wenn die Bytes kein gültiges UTF-8 sind. Das ist die mitteleuropäische Codepage, so bleiben in einem rumänischen, polnischen oder tschechischen Export aus einem älteren Excel alle Buchstaben erhalten. Eine westeuropäische Datei, die als Windows-1252 gespeichert ist, kommt größtenteils richtig an (é, ü und ç liegen auf denselben Bytes), macht aber aus à ein ŕ, aus è ein č und aus ñ ein ń. Bitte diese Kunden also um „CSV UTF-8“ oder .xlsx. Für Excel-Arbeitsmappen wird das Paket read-excel-file erst geladen, wenn jemand eine auswählt. Seiten, die nie eine .xlsx sehen, laden es also nie herunter. Alte binäre .xls-Dateien werden mit der Bitte um .csv oder .xlsx abgelehnt.
$ npx wingo-ui@latest add spreadsheetZwei Details beim Upload sorgen für weniger kaputte Dateien. Ein Link Download a template erzeugt eine CSV mit deinen Feld-Labels und ihren example-Werten (templateFileName gibt ihr den Namen). Und der Schalter „The first row is a header“ hilft bei Exporten, die direkt mit Daten anfangen.
Wie sollte eine UI zum Zuordnen der CSV-Spalten funktionieren?
Eine gute UI, mit der man CSV-Spalten zuordnen kann, fragt so wenig wie möglich. Jedes Feld bekommt eine Zeile: sein Label und sein Typ, ein Select mit den Spalten der Datei und ein Beispielwert aus der gewählten Spalte. Wenn sich der Wizard öffnet, zeigt jedes Feld schon auf die Spalte, deren Überschrift zu seinem Label, seiner id oder einem Alias passt, ohne Rücksicht auf Groß- und Kleinschreibung, Akzente und Satzzeichen. So passt „company_name“ zu „Company name“. Exakte Namen bekommen den Score 1, Teiltreffer weniger, und ein Paar entsteht erst ab einem Score von 0,5. Die Paare mit den besten Scores werden zuerst gebildet, zwei ähnliche Überschriften streiten sich also nie um ein Feld. Zugeordnete Paare tragen das Badge „Matched“.
Die Regeln, die verhindern, dass etwas schiefgeht:
- Jede Spalte wird nur einmal verwendet. Wählst du eine Spalte, die schon ein anderes Feld nutzt, wandert sie hinüber, damit dieselben Daten nicht zweimal importiert werden.
- „Continue“ bleibt deaktiviert, bis jedes Pflichtfeld eine Spalte hat, und die Meldung nennt die fehlenden.
- Jedes Feld hat die Option „Don't import“, zusätzliche Spalten stören also nicht.
- Dateien ohne Kopfzeile lassen sich trotzdem zuordnen: Spalten mit E-Mail, Telefon, Datum und rumänischen IDs werden an ihren Werten erkannt.
Auf dem Handy öffnet sich das Spalten-Select als Bottom Sheet, denn ein Dropdown, das an einem Feld hängt, verdeckt den Daumen, der es geöffnet hat.
Wie korrigieren Nutzer fehlerhafte Zeilen, ohne den Import zu verlassen?
Prüf jede Zeile, bevor sich der Prüfschritt öffnet, markier jede fehlerhafte Zelle mit dem Grund und lass sie direkt in der Tabelle korrigieren, wo sie sofort neu geprüft wird. Die Zeilen werden schon geprüft, während die Person noch zuordnet (große Dateien in Häppchen von 500 Zeilen, immer dann, wenn der Browser gerade nichts zu tun hat, damit 10.000 Zeilen die Seite nicht einfrieren). Der Prüfschritt ist also fertig, sobald er sich öffnet:
- Ein Filter für All, With errors und Valid.
- Fehlerhafte Zellen bekommen eine rote Wellenlinie und einen Tooltip mit dem Grund („Not an email address“, „Duplicate of row 12“).
- Ein Klick auf eine fehlerhafte Zelle bearbeitet sie direkt. Enter speichert, Escape bricht ab, und die Zeile wird sofort neu geprüft. Nur Zellen mit Fehlern liegen in der Tab-Reihenfolge, wer die Tastatur nutzt, springt also mit Tab von einer zur nächsten.
- Ein Button mit Verbotssymbol überspringt eine einzelne Zeile, und „Skip rows with errors“ lässt alle übrigen fehlerhaften Zeilen weg und schreibt sie in den Bericht.
Setz allowSkipInvalid={false}, wenn jede Zeile von Hand korrigiert oder übersprungen werden muss, bevor „Import“ aktiv wird.
Duplikate brauchen einen Schlüssel. Gib uniqueField="email" und die E-Mails, die schon in deiner Datenbank stehen, als existingKeys mit. Wiederholungen innerhalb der Datei werden zu Fehlern, Zeilen, die es schon gibt, bekommen ein Badge „Exists“, und ein Select fragt, ob sie übersprungen, aktualisiert oder noch einmal angelegt werden. Dein onImport bekommt diese Wahl als context.strategy. Bei einer großen Tabelle holst du nur die Schlüssel, nicht die Datensätze.
$ npx wingo-ui@latest add csv-importWie schicke ich die Zeilen mit Fortschrittsbalken und Abbrechen-Button?
onImport bekommt die gültigen, nicht übersprungenen Zeilen und einen Kontext mit vier Dingen: strategy, onProgress(done) für den Fortschrittsbalken, ein signal, das der Abbrechen-Button abbricht, und rows, die Zeilen aus dem Prüfschritt in derselben Reihenfolge, deren index die Zeilennummer ist, wie die Tabelle sie zeigt. Schick die Zeilen in Batches, damit sich der Balken bewegt und Abbrechen zwischen zwei Requests greift:
Wirft die Funktion einen Fehler, zeigt der Wizard dessen Meldung mit einem Button „Try again“. Abbrechen bricht context.signal ab, der offene fetch-Aufruf schlägt fehl, und der Lauf endet mit „Import cancelled after N rows“, wobei N der letzte Wert ist, den du an onProgress gegeben hast. Der Wizard bricht das Signal auch beim Unmount ab. Wer wegnavigiert, lässt also keine Requests weiterlaufen. Die Zusammenfassung zeigt dann Kacheln für angelegte, aktualisierte, übersprungene und fehlgeschlagene Zeilen, listet die Zeilen, die es nicht geschafft haben, mit ihrem Grund auf und bietet Download failed rows an: eine CSV mit einer Spalte „Error“, die die Person korrigieren und erneut importieren kann.
Warum muss der Server die Zeilen noch einmal prüfen?
Jeder kann beliebiges JSON an /api/contacts/import posten. Die Prüfungen im Browser sind also für die Person da, die Prüfungen auf dem Server für deine Daten. Die Komponente exportiert validateImportRows, eine reine Funktion, die die Prüfungen des Wizards auf rohe Zeilen anwendet. csv-import.tsx beginnt aber mit "use client", also pack die Regeln für den Server in ein eigenes Modul:
Auch die andere Richtung braucht Sorgfalt. Der Bericht der fehlgeschlagenen Zeilen und die Vorlage sind CSV-Dateien, die Leute in Excel öffnen, und eine Zelle, die mit = beginnt, kann als Formel ausgeführt werden. Die OWASP-Seite zu CSV Injection (opens in a new tab) nennt als eine Abwehr, solchen Zellen ein einfaches Anführungszeichen voranzustellen, und warnt, dass Excel es nach Speichern und erneutem Öffnen verlieren kann (geprüft im Oktober 2026). toCsv aus den Spreadsheet-Helfern macht das standardmäßig für Zellen, die mit =, +, -, @, Tab oder Wagenrücklauf beginnen, und der Importer entfernt dieses Anführungszeichen wieder, wenn eine Zelle wie '=SUM(A1) in einer Datei zurückkommt.
Was ändert sich auf dem Handy?
Unter 768px füllt der Wizard seinen Container mit einem Sticky Header und Footer und 48px hohen Buttons (fullScreenOnMobile, standardmäßig an, gib dem Container also eine Höhe). Der Stepper wird zu einer kompakten Fortschrittszeile, die Zeilen im Prüfschritt werden zu Karten, und ein Tipp auf einen Wert öffnet ein Sheet mit dem Feld, seinem Fehler und einem einzigen Button zum Speichern. Wer den Import aus einer E-Mail auf dem Handy öffnet, kann ihn also trotzdem abschließen. Mehr zu diesem Muster steht im Beitrag über responsive Tabellen, die zu Karten werden.
Mit welchen Dateien sollte ich einen CSV Importer testen?
Teste mit den Dateien, die Kunden wirklich schicken werden, denn der saubere Export, den du selbst gemacht hast, besteht jede Prüfung. Leg dir einen kleinen Ordner damit an und schick jede Datei vor dem Launch durch alle vier Schritte:
- Eine CSV mit Semikolon und Dezimalkomma, aus einem Excel mit europäischer Ländereinstellung.
- Eine Datei mit akzentuierten Namen, gespeichert als Windows-1250, eine als Windows-1252 (achte auf à, è und ñ) und eine mit einer UTF-8-Byte-Order-Mark.
- Einen Export ohne Kopfzeile.
- Zellen in Anführungszeichen, die Kommas, verdoppelte Anführungszeichen und Zeilenumbrüche enthalten.
- Eine Arbeitsmappe mit mehreren Tabellenblättern und eine alte .xls-Datei, die mit einer klaren Meldung abgelehnt werden sollte.
- Eine Datei über dem Zeilenlimit.
maxRowssteht standardmäßig auf 10.000; der Rest wird abgeschnitten, und eine Warnung sagt das. - Denselben Kunden zweimal und einen Kunden, den du schon hast.
Wenn jede dieser Dateien entweder sauber importiert wird oder mit einer Meldung endet, die sagt, was zu ändern ist, wird das Support-Ticket aus dem ersten Absatz nie geschrieben.
Soll ich den Import selbst bauen oder einen gehosteten Importer nutzen?
Nimm einen gehosteten Importer, wenn du das Ganze lieber im Dashboard eines Anbieters konfigurierst, als den Code selbst zu verantworten. CSVbox (opens in a new tab) ist ein Beispiel: Ein JS-Snippet fügt ein Import-Modal hinzu, Dateien werden auf seiner Infrastruktur in einer Region deiner Wahl verarbeitet, und sein Private Mode parst, ordnet zu und validiert im Browser der Person und schickt die Zeilen an deinen eigenen Endpoint (geprüft im Oktober 2026). Nimm eine Komponente, wenn du den Importer in deinem Repository haben willst, typisiert gegen deine eigenen Felder, zusammen mit dem Rest der App reviewt und versioniert und im selben Look. CSV Import ist eine Pro-Komponente (Preise); jeder Text ist eine labels-Prop, und tone, size und stepper ändern das Aussehen, ohne dass du neu stylen musst.
Wie sieht der fertige Import-Assistent für CSV und Excel aus?
Es ist eine einzige Client-Komponente, die die Felder, das onImport mit Batches und die Duplikatprüfung zusammenbringt. Excel-Arbeitsmappen laufen durch dieselben vier Schritte wie CSV-Dateien, dieselbe Seite funktioniert also auch als Excel-Import-Assistent:
Für die Schritte selbst außerhalb eines Imports lies das Tutorial zum React Multi Step Form, und für die Dropzone allein die Anleitung zum React File Upload. Der Guide zu React-Formularkomponenten behandelt den Aufbau der Felder, den all diese Komponenten teilen, und weitere Anleitungen zu Komponenten findest du in der Kategorie Komponenten.
Nächster Schritt
Installier den Wizard mit npx wingo-ui@latest add csv-import, stell fields auf die Tabelle ein, die du am häufigsten importierst, und schick deinen chaotischsten echten Export hindurch, bevor ein Kunde es tut.
Häufige Fragen
Wie importiere ich eine CSV-Datei in React?
Lies die Datei im Browser mit der File API, parse sie mit einem Parser nach RFC 4180, der Anführungszeichen und Zeilenumbrüche in Zellen versteht, ordne dann die Spalten deinen Feldern zu und validiere jede Zeile, bevor du sie abschickst. Eine Wizard-Komponente wie der CSV Import von Wingo UI fasst diese Schritte zusammen, du beschreibst also nur die Felder und schreibst die Funktion, die die Zeilen speichert.
Kann ein React CSV Importer Excel-Dateien lesen?
Ja, wenn er .xlsx im Browser parst. Der CSV Import von Wingo UI liest .xlsx über read-excel-file, das erst geladen wird, wenn jemand eine Arbeitsmappe auswählt, und lässt das Tabellenblatt wählen. Alte binäre .xls-Dateien lehnt er mit der Bitte um .csv oder .xlsx ab.
Wie sollte die Spaltenzuordnung bei einem CSV-Import funktionieren?
Weise jedem Feld vorab die Spalte zu, deren Überschrift zu seinem Namen oder einem seiner Aliase passt, ohne Rücksicht auf Groß- und Kleinschreibung, Akzente und Satzzeichen, und lass jedes Paar über ein Select ändern. Sperr den nächsten Schritt, bis jedes Pflichtfeld eine Spalte hat, und nenn die Felder, die noch fehlen.
Sollte ich CSV-Zeilen im Client oder auf dem Server validieren?
Beides. Prüfungen im Client geben im Prüfschritt sofort Feedback, so korrigieren die Leute Fehler, bevor sie absenden. Der Server muss noch einmal prüfen, denn jeder kann deinen Import-Endpoint mit beliebigem JSON aufrufen.
Wie gehe ich bei einem CSV-Import mit doppelten Zeilen um?
Wähl ein Feld als Schlüssel, etwa die E-Mail, markier Wiederholungen innerhalb der Datei als Fehler und kennzeichne Zeilen, deren Schlüssel es in deinen Daten schon gibt. Lass die Person dann entscheiden, ob diese Zeilen übersprungen, aktualisiert oder noch einmal angelegt werden, und gib diese Wahl an den Server weiter.
- CSV
- Excel
- Datenimport
- Formulare
- Mobile UI


