csv Dateien einlesen mit Cake
Viele von euch werden das Problem kennen. Ein Kunde wünscht, dass aus Office Programmen Daten in die Webanwendung eingelesen werden können sollen. Was bei reinem Text gut mit Copy&Paste klappt, braucht bei Exceldateien schon ein anderes Kaliber.
Daher hier eine Funktion, die es ermöglicht, aus Excel exportierte CSV Dateien mithilfe von CakePHP komfortabel in die Datenbank einzulesen. Doch ein Schritt nach dem anderen.
Dieses Beispiel ist für CakePHP Version 1.11
CSV?
“Eine CSV-Datei ist eine Textdatei zur Speicherung oder zum Austausch einfach strukturierter Daten. Das Kürzel CSV steht dabei für Character Separated Values, Comma Separated Values oder Colon Separated Values, weil die einzelnen Werte durch ein spezielles Trennzeichen, beispielsweise das Komma oder Semikolon, getrennt werden. Ein allgemeiner Standard für das Dateiformat existiert nicht.”
Quelle: Wikipedia.de
Ich habe mir nun mal eine kleine Beispieltabelle gestrickt, wie sie auch in Excel oder OpenOffice vorkommen kann:
| Vorname | Nachname | Firma | |
|---|---|---|---|
| Max | Mustermann | Mustermann GmbH | max@example.com |
| Maria | Mustermann | Mustermann GmbH | maria@example.com |
| Silke | Mustermann | Mustermann GmbH | silke@example.com |
Diese Tabelle wird nun als CSV Datei abgespeichert. Es entsteht eine Datei, deren Inhalt zum Beispiel so aussehen kann
-
Vorname;Nachname;Firma;E-Mail
-
Max;Mustermann;Mustermann GmbH;max@example.com
-
Maria;Mustermann;Mustermann GmbH;maria@example.com
-
Silke;Mustermann;Mustermann GmbH;silke@example.com
Diese Daten könnten nun in die Datenbank eingespeichert werden, doch ich mache hier noch einen kleinen Trick, um später Arbeit zu sparen. Ich ändere in der Excel Datei die erste Zeile wie folgt:
Aus Vorname, Nachname, Firma, E-Mail wird -> vorname,nachname,firma,email oder in der CSV Datei:
-
vorname;nachname;firma;email
Diese Headerdaten stimmen mit den Spaltennamen meiner Datenbanktabelle Tabelle überein. Hier ein Beispiel einer solchen Tabelle:
-
CREATE TABLE `morg_clients` (
-
`id` int(11) NOT NULL AUTO_INCREMENT,
-
`vorname` int(11) NOT NULL DEFAULT ’0′,
-
`firma` varchar(255) collate latin1_general_ci NOT NULL DEFAULT ”,
-
`email` varchar(255) collate latin1_general_ci NOT NULL DEFAULT ”,
-
`nachname` varchar(255) collate latin1_general_ci NOT NULL DEFAULT ”,
-
PRIMARY KEY (`id`)
-
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
Es ist in diesem Fall beabsichtigt, dass die Tabelle nicht in der Reihenfolge mit der Exceldatei übereinstimmt, da dies in der “Wildnis” meistens ebenfalls nicht der Fall ist.
Nachem ihr sicher schon ganz heiß auf den Code seid (oder gleich bis hier hin runtergescrollt habt, da ihr sowieso wisst, was CSV Dateien sind) will ich nun auch dazu kommen.
Beginnen wir mit dem View in diesem Fall:
[root]/[app]/views/examples/csv.thtml
-
<form action="<?php echo $html->url(‘/examples/csv/’); ?>" method="post" enctype="multipart/form-data">
-
<div class="required">
-
<?php echo $form->labelTag(‘Example/file’, ‘Datei:’);?>
-
<?php echo $html->file(‘Example/file’);?>
-
<?php echo $html->tagErrorMsg(‘Example/file’, ‘Dateiname darf nicht leer sein.’);?>
-
</div>
-
<?php echo $html->submit(‘Upload’);?>
-
</form>
Wie man sieht ein ganz einfaches Formular mit einem File->Upload. Hier wird die CSV Datei eingegeben und dann weiterverarbeitet.
Nun folgt die Magie, sprich der Controller:
[root]/[app]/controllers/examples_controller.php
Hier wird zunächst die Datei eingelesen. Danach wird die Datei aufgespalten, wobei das Semikolon als Trennzeichen benutzt wird. So bekommt jeder Datensatz die richtigen Werte.
Ausgabebeispiel
Nun wird die erste Zeile genutzt, um ein Assoziatives Array aus dem bestehenden Array zu erschaffen.
-
//Array in Assoziatives Array anhand Array 0 verwandeln
-
$i=0;
-
foreach ($neue_datei as $elem) {
-
if ($i == 0) {
-
foreach ($elem as $key) $key_array[] = $key;
-
} else {
-
$j=0;
-
$elem2 = $elem;
-
$neue_datei[$i] = "";
-
foreach ($elem2 as $input) {
-
$neue_datei[$i][$key_array[$j]] = $input;
-
$j++;
-
}
-
-
}
-
$i++;
-
}
-
$i=0;
Die erste Schleife durchläuft das gesamte Array. Ist dabei die Variable $i noch 0, so befinden wir uns im Zuweisungsdatensatz (vorname,nachname…). Dieser wird in dem Array $key_array abgespeichert.
Ist dies geschehen, werden für jeden weiteren Datensatz im Array die Schlüssel des Datensatzes nach der Vorgabe geändert. Abschließend wird der erste Datensatz, die Zuweisung, aus dem Array mittels array_splice entfernt. Wir haben nun folgendes Array:
-
[0] = Array([vorname] => "Max", [nachname] =>"Mustermann", [firma] => "Mustermann GmbH", [email]=>"max@example.com")
-
[1] = Array([vorname] => "Maria", [nachname] =>"Mustermann", [firma] => "Mustermann GmbH", [email]=>"maria@example.com")
-
[2] = Array([vorname] => "Silke", [nachname] =>"Mustermann", [firma] => "Mustermann GmbH", [email]=>"silke@example.com")
-
);
Hier ist die Magie wahr geworden, wir können dieses Array nun problemlos durch eine Speicherschleife laufen lassen:
-
foreach ($neue_datei as $elem) {
-
$this->data[‘Example’] = $elem;
-
$this->data[‘Example’][‘id’] = "";
-
$this->Example->save($this->data);
-
}
-
-
//Ende des Codes zur Vervollständigung
-
$this->Session->setFlash(‘Datensätze erfolgreich eingelesen’);
-
$this->redirect(‘/examples/csv’);
-
}
-
}
Egal in welcher Reihenfolge nun die Datenbanktabelle definiert ist, durch die assoziative Zuweisung der Datensatzwerte und ihrer Schlüssel können wir nun den Datensatz ohne Probleme speichern.
Ich hoffe, dieses ausführliche Beispiel hat euch geholfen, CSV und CakePHP etwas besser zu verstehen.
Bis zum nächsten Mal, Bye!
Kategorie: CakePHP | 1 Kommentar »
Veröffentlicht am Mittwoch, den 25. Juli 2007 um 10:36 Uhr veröffentlicht
Du kannst einen Kommentar schreiben, oder einen Trackback auf deiner Seite einrichten.
