Importieren Sie eine CSV-Datei in den Laravel-Controller und fügen Sie Daten in zwei Tabellen ein

Lesezeit: 7 Minuten

Benutzeravatar von Devin Gray
Devin Gray

Also ich bin ein absoluter Noob was Laravel angeht und probiere hier mal was aus. Ich möchte eine CSV-Datei in zwei Tabellen importieren, ich habe eine Tabelle namens Listen, die den Listennamen und a erhält client_id.

Dann habe ich eine Tabelle namens Kunden, die sowohl den Namen als auch die Kontaktnummer des Nachnamens erhält client_id und ein list_id.

Was ich erreichen möchte, ist, eine CSV-Datei zu importieren, die den Dateinamen übernimmt und in der Listentabelle speichert, dann ein Array durch die CSV-Datei erstellt und die Daten mit der Liste und den Client-IDs in die Kundentabelle importiert.

Ich habe den ersten Teil erledigt und er wird korrekt in die Listentabelle eingefügt. Wie erstelle ich jetzt ein Array aus der CSV-Datei, die sich im Speicher / in den Dokumenten befindet, und füge das dann in die Kundentabelle ein?

namespace App\Http\Controllers;

use Input;
use DB;
use Illuminate\Http\Request;
use App\Http\Requests\ListsRequest;
use App\Lists;
use App\Clients;
use App\Http\Requests;
use App\Http\Controllers\Controller;

class ListsController extends Controller {

    public function index()
    {
        // $list_items = Lists::all();
        $clients = Clients::all();

        return view('lists.show', compact('clients'));
    }

    public function store(Requests\ListsRequest $request)
    {
        $input = $request->input();
        Lists::create($input);

        if (Input::hasFile('name'))
        {

            $file = Input::file('name');
            $name = time() . '-' . $file->getClientOriginalName();

            $path = storage_path('documents');

            $file->move($path, $name);

            // All works up to here
            // All I need now is to create an array
            // from the CSV and insert into the customers database
        }
    }
}

Ich habe mich für die Antwort entschieden, die ich akzeptiert hatte, aber ich habe auch mit der anderen Antwort gespielt und es so zum Laufen gebracht.

public function store(Requests\ListsRequest $request)
{
    $input = $request->input();
    $client_id = $request->input('client_id');

    if (Input::hasFile('name'))
    {
        $file = Input::file('name');
        $name = time() . '-' . $file->getClientOriginalName();
        $path = storage_path('documents');

        Lists::create(['client_id' => $client_id, 'name' => $name]);

        $reader = Reader::createFromPath($file->getRealPath());
        // Create a customer from each row in the CSV file
        $headers = array();

        foreach ($reader as $index => $row)
        {
            if ($index === 0)
            {
                $headers = $row;
            } else
            {
                $data = array_combine($headers, $row);
                Customers::create($data);
            }
        }

        $file->move($path, $name);

        return view('clients');
    }
}

  • Schauen Sie sich das erste an stackoverflow.com/questions/21063008/… Sie können nicht einfach direkt in die Datenbank einfügen, wie Sie es tun. Wenn der Link keine Hilfe bietet, lassen Sie es mich wissen

    – Maytham Fahmi

    5. Februar 2016 um 9:21 Uhr

  • Ich versuche das jetzt 🙂 Danke, werde dich in ein paar wissen lassen, wie es geht

    – Devin Grey

    5. Februar 2016 um 9:23 Uhr

  • Okay, ich habe versucht, was in der bearbeiteten Frage oben zu sehen ist, aber jetzt bekomme ich nur einen leeren Bildschirm, selbst wenn ich nur „Hallo“ zurückgebe, wo ich es getan habe

    – Devin Grey

    5. Februar 2016 um 9:36 Uhr

  • Könnten Sie helfen, die Logik in dem Bereich zu erklären, in dem ich hinzugefügt habe?

    – Devin Gray

    5. Februar 2016 um 9:36 Uhr

  • Es ist wichtig, das Problem Schritt für Schritt zu lösen. Wenn also kein Hallo zurückgegeben wird, bedeutet dies, dass die Datei nicht erhalten wurde oder Ihre if-Anweisung falsch zurückgibt. Versuchen Sie zum Spaß, dd($input) vor der if-Anweisung zu schreiben, um zu sehen if your controller is life und finden Sie heraus, ob $input die Dinge enthält, die Sie erwartet haben

    – Maytham Fahmi

    5. Februar 2016 um 9:57 Uhr

Benutzeravatar von Maytham Fahmi
Maytham Fahmi

Es gibt 3 Schritte, um eine CSV-Datei zu lesen und in die Datenbank in Laravel zu importieren.

  1. CSV-Datei lesen
  2. Konvertieren Sie es in ein Array
  3. Erstellen Sie abschließend Datensätze in unserer Datenbank.

Bevor wir beginnen, habe ich ein Beispiel erstellt test.csv Datei und lege sie in meinen öffentlichen Ordner unter Dateiordner:

name,email,password
user1,[email protected],pasxxxxxxxxxword
user2,[email protected],pasxxxxxxxxxword
user3,[email protected],pasxxxxxxxxxword

Schritt 1 und 2; Ich habe eine Hilfsfunktion namens erstellt csvToArrayich habe es vorerst nur in meinen Controller gesteckt (diese Funktion ist davon inspiriert Verknüpfung) liest es einfach die CSV-Datei und konvertiert sie in ein Array:

function csvToArray($filename="", $delimiter=",")
{
    if (!file_exists($filename) || !is_readable($filename))
        return false;

    $header = null;
    $data = array();
    if (($handle = fopen($filename, 'r')) !== false)
    {
        while (($row = fgetcsv($handle, 1000, $delimiter)) !== false)
        {
            if (!$header)
                $header = $row;
            else
                $data[] = array_combine($header, $row);
        }
        fclose($handle);
    }

    return $data;
}

Schritt 3; Und hier ist mein letzter Schritt, Array lesen und in unsere Datenbank einfügen:

public function importCsv()
{
    $file = public_path('file/test.csv');

    $customerArr = $this->csvToArray($file);

    for ($i = 0; $i < count($customerArr); $i ++)
    {
        User::firstOrCreate($customerArr[$i]);
    }

    return 'Jobi done or what ever';    
}

Notiz: Diese Lösung setzt voraus, dass Sie ein Modell in Ihrem Laravel-Projekt und die richtige Tabelle in Ihrer Datenbank haben.

wenn du benutzt dd($customerArr) du wirst das bekommen
Geben Sie hier die Bildbeschreibung ein

  • Ich denke, das ist ein guter Ansatz. Aber wie sieht es mit einer großen CSV wie 100 000 Zeilen aus? Das Array wird eine große Größe haben und ich könnte Probleme mit dem Arbeitsspeicher haben.

    – Rolli

    18. August 2017 um 16:36 Uhr

  • Der Header hängt in diesem Fall von Ihrem Datenmodell ab, wie im Hinweis erwähnt. In meinem Fall ist es das Benutzermodell und enthält Name, E-Mail-Passwort. du tust es selbst und probierst es aus. falls ich dich missverstanden habe lass es mich wissen.

    – Maytham Fahmi

    28. Mai 2018 um 17:28 Uhr


  • @maytham-ɯɐɥʇʎɐɯ Können Sie mir einfach sagen, wie Sie das Passwort überhaupt verschlüsseln, nachdem Sie die CSV-Datei hochgeladen haben?

    – Vergifteter Hashkey

    26. April 2021 um 19:51 Uhr

  • @ToxifiedHashkey Ich habe vor einigen Jahren aufgehört, mit Laravel zu arbeiten. aber die bcrypt-Funktion können Sie googeln und eine Funktion finden, um das Passwort zu verschlüsseln. aber $customerArr[$i] ist jedes Objekt, das Sie importieren, können Sie konzeptionell etwas tun, ohne es zu testen und zu validieren. $KundeArr[$i]->Passwort = bcryptFunction($customerArr[$i]->Passwort) Dies überschreibt das Textpasswort mit dem verschlüsselten Passwort.

    – Maytham Fahmi

    27. April 2021 um 14:57 Uhr


  • @maytham-ɯɐɥʇʎɐɯ Vielen Dank für diesen Tipp: D

    – Vergifteter Hashkey

    27. April 2021 um 15:07 Uhr

In deinem store() Methode, erstellen Sie den Datensatz in Ihrer lists Tabelle, iterieren Sie dann über den Inhalt der CSV-Datei und fügen Sie die Daten in die ein customers Tisch. Sie sollten eine erstellen Beziehung zwischen Kunden und Listen zu diesem Zweck. Sie würden auch besser dran sein, so etwas wie das zu verwenden Das CSV-Paket von PHP League zum Lesen solcher Dateien:

public function store(AddCustomersRequest $request)
{
    // Get uploaded CSV file
    $file = $request->file('csv');

    // Create list name
    $name = time().'-'.$file->getClientOriginalName();

    // Create a list record in the database
    $list = List::create(['name' => $name]);

    // Create a CSV reader instance
    $reader = Reader::createFromFileObject($file->openFile());

    // Create a customer from each row in the CSV file
    foreach ($reader as $index => $row) {
        $list->customers()->create($row);
    }

    // Redirect back to where you need with a success message
}

  • Ich habe dazu die Funktion von @maytham-ɯɐɥıλɐɯ verwendet, aber ich habe auch mit Ihrer Antwort herumgespielt, um zu sehen, wie das geht. Ich bearbeite meine Frage, damit Sie sie sehen können.

    – Devin Grey

    5. Februar 2016 um 13:03 Uhr

Benutzeravatar von Koushik Das
Kushik Das

@maytham Die Lösung von Maytham wird gut funktionieren. Es wird jedoch ein großes Problem geben, wenn Sie versuchen, mit großen Datenmengen zu arbeiten. Selbst wenn Sie 1000 Zeilen erstellen, wird dies ein Problem verursachen, da 1000 separate Insert-Anweisungen erstellt werden. Ich werde nur die dritte Methode von ihm bearbeiten und meine eigene Eingabe hinzufügen

public function importCsv()
{
    $file = public_path('file/test.csv');

    $customerArr = $this->csvToArray($file);
    $data = [];
    for ($i = 0; $i < count($customerArr); $i ++)
    {
        $data[] = [
            'column_name1' => 'value',
            'column_name2' => 'value2',
            .. so..on..and..on
        ];
        //User::firstOrCreate($customerArr[$i]);
    }
    DB::table('table_name')->insert($data);
    return 'Jobi done or what ever';    
}

Dadurch wird die Datenbank einmal aufgerufen, um so viele Zeilen einzufügen, wie Sie möchten. Sei es 1000, 100000 oder was auch immer.
Wenn Sie jedoch eine große CSV-Datei haben, ist dies ebenfalls ein Problem, da Sie Chunks einfügen müssen. Wie bei PostgreSQL ist mir aufgefallen, dass Sie bis zu 65000 Zeilen in eine Anweisung einfügen können. Vielleicht irre ich mich mit der Zahl, aber es gibt eine Grenze in jeder Datenbank, und Sie müssen danach suchen.

  • Ja, das ist ein sehr guter Punkt. Wenn Sie eine große CSV-Datei haben, können Sie wahrscheinlich nicht alles in einem Array im Arbeitsspeicher speichern, bevor Sie mit dem Einfügen der Daten in die DB beginnen. Daher müssen Sie die Daten in Blöcken einfügen, während Sie sie aus der CSV-Datei lesen . Vielen Dank.

    – HartleySan

    24. September 2018 um 12:43 Uhr

  • Richtig. Ich habe auch gesehen, dass die Anzahl der Zeilen in einer Einfügung begrenzt ist.

    – Koushik Das

    24. September 2018 um 15:55 Uhr

1439730cookie-checkImportieren Sie eine CSV-Datei in den Laravel-Controller und fügen Sie Daten in zwei Tabellen ein

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy