Ankündigung

Einklappen
Keine Ankündigung bisher.

CSV Datei splitten

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • CSV Datei splitten

    Abend,
    ich experimentiere gerade etwas mit CSV Dateien herum. Zur zeit versuche ich eine große csv Datei in mehrere zu splitten, aufzuteilen. Habe irgendwo ein Script gefunden, es an meine Bedürfnisse angepasst. Läuft gut, aber leider schaffe ich es nicht in die "abgeschnittenen" CSV Dateien auch den Kopf mit anzufügen , also die Kopfzeile der Ausgangsdatei. Könnte eine Idee gebrauchen. Danke

    Code:
    <?php
    
    $dateiname = "test.csv";
    
    $lines = 100; /* Anzahl der Zeilen */
    
    $datei = 1;   /*  Datei Nummer  */
    $zeile = 0;    /* Zeilen Zähler bis $lines erreicht ist */
    $allez = 0;    /* Gesamt Zeilen Zähler  */
    $fpx = array();  /* handler um neue Dateien zu erstellen */
    
    $godatei = "CSV_datei_".$datei.".csv";  /*  neue $godatei Nr. 1  */
    echo "<br />neue Datei: ".$godatei."\r\n";
    
    /* read datei öffnen */
    $fp = @fopen($dateiname, "r") or die ("Kann Datei nicht lesen.");
    
    $fpx[$datei] = @fopen($godatei, "w+") or die ("Kann Datei nicht schreiben.");
    
    /* datei zeilenweise auslesen */
    while($line = fgets($fp, 1024)){
        $zeile++;
        if($zeile == $lines){
            fclose($fpx[$datei]); /* die alte $godatei datei schliessen */
            $datei++;
    
            $godatei = "CSV_datei_".$datei.".csv";
            echo "<br />neue Datei: ".$godatei."\r\n";  /*  neue $godatei mit fortlaufender Nr.  */
            $fpx[$datei] = @fopen($godatei, "w+") or die ("Kann Datei nicht schreiben.");
            $zeile = 0;  /* Zeilen Zähler zurücksetzen */
        }
       // dachte an dieser Stelle den Kopf einzufügen
        fwrite($fpx[$datei],$line); /* in neue datei schreiben */
        $allez++;
    }
    /* read datei schliessen */
    fclose($fp);
    
    echo "<br />\r\n";
    echo "<br />Zeilen Gesamt: ".$allez."\r\n";
    echo "<br />Dateien Gesamt: ".$datei."\r\n";
    
    ?>

  • #2
    Was unterscheidet denn Deine Kopfzeile vom Rest?

    Kommentar


    • #3
      Hallo,

      wenn die CSV konform aufgebaut ist, kannst Du Dir die Kopfzeile bspw. ganz einfach aus einem Array holen und die restlichen Zeilen in "Brocken" verteilen.
      PHP-Code:
      $aFileLines file'datei,csv'FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES );

      $sHeadline array_shift$aFileLines );
      $aChunks array_chunk$aFileLines100 ); // je nachdem, wieviele Elemente in einer neuen Datei max. sein sollen

      foreach ( $aChunks as $index=>$chunk )
          
      file_put_contents'newfile_' . (string)$index '.csv'array_unshift($chunk$sHeadline) ); 
      ungetestet, aber das Prinzip sollte klappen.

      Kommentar


      • #4
        Guten Morgen,

        schöne neue Syntax Vokabeln . Danke ich probier mal rum...

        Kommentar


        • #5
          In einer CSV können Zeilenumbrüche innerhalb eines Datensatzes vorkommen. Funktionen wie file oder fgets sind damit für eine allgemeine Lösung nicht sinnvoll.

          Kommentar


          • #6
            Zitat von erc Beitrag anzeigen
            In einer CSV können Zeilenumbrüche innerhalb eines Datensatzes vorkommen.
            Ich denke, dass das mit den duoble quotes geregelt wird, daher ist das simple zeilenweise einlesen nicht auf alle csv´s anwendbar.

            https://tools.ietf.org/html/rfc4180

            Kommentar


            • #7
              Nu...

              Kommentar


              • #8
                Habe für CSV's gute Erfahrungen mit dem SplFileObject gemacht. Sollte auch mit großen CSV-Files zurechtkommen, da nicht alles als Array in den Speicher gezogen wird.
                Mal als Ansatz, die FLAGS können bei Bedarf noch ergänzt werden durch SplFileObject::SKIP_EMPTY und SplFileObject:: DROP_NEW_LINE:
                PHP-Code:
                $file = new SplFileObject($fileName'r+');
                $file->setFlags(SplFileObject::READ_CSV );
                $file->setCsvControl(";",""");

                $title = array();
                foreach(
                $file as $key => $row){
                  if(
                $key == 0) {
                    
                $title = $row;
                  }
                  else {
                    //data
                    var_dump(
                $row);  //test
                  }

                Am Rande: Mit SplFileObject:: DROP_NEW_LINE werden auch Zeilenumbrüche innerhalb von mit Doublequotes umgebenden strings entfernt. k.A., ob diese Erfahrung aus Zeiten von PHP 5.3 noch zutrifft.

                Kommentar


                • #9
                  @jspit dein Ansatz bezieht sich darauf große csv Dateine nicht zu teilen?

                  Kommentar


                  • #10
                    Jnein.
                    Große CSV-Dateien können mit dem Ansatz eingelesen und verarbeitet werden, ohne das im Speicher große Arrays vorgehalten werden müssen.
                    Dein Ziel, in mehrere kleine zu splitten (warum auch immer), kannst du damit auch realisieren. Mit $key hast du sozusagen die Zeilennummer und in $title dein Array mit den Überschriften. In dem Teil wo jetzt nur var_dump steht gehört dann noch der Code welcher viele kleine CSV-Dateien ausgibt.

                    Kommentar


                    • #11
                      Um welche Grössenordnung handelt es sich denn überhaupt, um mal einen Ansatzpunkt zu erhalten.

                      Kommentar


                      • #12
                        @protestix

                        Größenordnung ist relativ, habe eine Testdatei mit 170.000 Einträgen (ca. 22 MB Groß), mir geht es da eher um die Technik. Manche Server akzeptieren ja so große Dateien nicht. Hätte da gern die Möglichkeit sie teilen zu können. Also mir ist erstmal nichts besseres eingefallen als Sie zu teilen.

                        Kommentar

                        Lädt...
                        X