Frage

Ich verwende fputcsv in PHP für die Ausgabe einer kommagetrennte Datei einer Datenbankabfrage. Wenn die Datei in gedit in Ubuntu zu öffnen, sieht es richtig - jeder Datensatz einen Zeilenumbruch hat (keine sichtbaren Zeilenumbruch Zeichen, aber Sie können jeder Datensatz sagen wird abgetrennt, und es in Openoffice-Tabelle zu öffnen ermöglicht es mir, die Datei korrekt zu sehen.)

Allerdings sind zu senden wir diese Dateien auf einem Client unter Windows und auf ihren Systemen, die Datei kommt als eine große, lange Linie. Öffnen Sie in Excel, erkennt es nicht mehrere Zeilen überhaupt.

Ich habe hier einige Fragen lesen, die ziemlich ähnlich sind, einschließlich dieser , das umfasst ein Link auf die wirklich informativ Groß Newline Schisma Erläuterung.

Leider können wir nicht nur unseren Kunden sagen, die Dateien in einem „intelligenteren“ Editor zu öffnen. Sie müssen in der Lage, sie in Excel zu öffnen. Gibt es eine programmatische Art und Weise, um sicherzustellen, dass die richtigen Zeilenumbrüche hinzugefügt werden, so dass die Datei in einem Tabellenkalkulationsprogramm auf jedem Betriebssystem geöffnet werden kann?

Ich verwende bereits eine benutzerdefinierte Funktion Anführungszeichen zu zwingen, um alle Werte, da fputcsv über sie selektiv ist. Ich habe versucht, so etwas wie dies zu tun:

function my_fputcsv($handle, $fieldsarray, $delimiter = "~", $enclosure ='"'){

        $glue = $enclosure . $delimiter . $enclosure;

    return fwrite($handle, $enclosure . implode($glue,$fieldsarray) . $enclosure."\r\n");

}

Aber wenn die Datei in einem Windows-Texteditor geöffnet wird, zeigt er immer noch als eine einzige lange Zeile nach oben.

War es hilfreich?

Lösung 8

Ich habe schließlich eine Antwort über auf Experten-Austausch erhalten; hier ist, was funktioniert hat:

function my_fputcsv($handle, $fieldsarray, $delimiter = "~", $enclosure ='"'){
   $glue = $enclosure . $delimiter . $enclosure;
   return fwrite($handle, $enclosure . implode($glue,$fieldsarray) . $enclosure.PHP_EOL);
}

anstelle von Standard fputcsv verwendet werden.

Andere Tipps

// Writes an array to an open CSV file with a custom end of line.
//
// $fp: a seekable file pointer. Most file pointers are seekable, 
//   but some are not. example: fopen('php://output', 'w') is not seekable.
// $eol: probably one of "\r\n", "\n", or for super old macs: "\r"
function fputcsv_eol($fp, $array, $eol) {
  fputcsv($fp, $array);
  if("\n" != $eol && 0 === fseek($fp, -1, SEEK_CUR)) {
    fwrite($fp, $eol);
  }
}

Dies ist eine verbesserte Version des @John Douthat des großen Antwort, die Erhaltung der Möglichkeit, benutzerdefinierte Trennzeichen und Gehäuse der Verwendung und fputcsv ursprünglichen Ausgangs Rückkehr:

function fputcsv_eol($handle, $array, $delimiter = ',', $enclosure = '"', $eol = "\n") {
    $return = fputcsv($handle, $array, $delimiter, $enclosure);
    if($return !== FALSE && "\n" != $eol && 0 === fseek($handle, -1, SEEK_CUR)) {
        fwrite($handle, $eol);
    }
    return $return;
}

Mit dem PHP-Funktion fputcsv schreibt nur \ n und nicht angepasst werden kann. Dies macht die Funktion wertlos für Microsoft-Umgebung, obwohl einige Pakete werden auch die Linux-Newline erkennen.

Immer noch die Vorteile des fputcsv hielten mich in eine Lösung graben die Newline-Zeichen zu ersetzen, kurz bevor in die Datei zu senden. Dies kann durch das Streamen des fputcsv zu der Build in php Temp Strom zuerst durchgeführt werden. Dann passen Sie die Zeilenende-Marke (n) zu, was Sie wollen und dann eine Datei zu speichern. Wie folgt aus:

function getcsvline($list,  $seperator, $enclosure, $newline = "" ){
    $fp = fopen('php://temp', 'r+'); 

    fputcsv($fp, $list, $seperator, $enclosure );
    rewind($fp);

    $line = fgets($fp);
    if( $newline and $newline != "\n" ) {
      if( $line[strlen($line)-2] != "\r" and $line[strlen($line)-1] == "\n") {
        $line = substr_replace($line,"",-1) . $newline;
      } else {
        // return the line as is (literal string)
        //die( 'original csv line is already \r\n style' );
      }
    }

        return $line;
}

/* to call the function with the array $row and save to file with filehandle $fp */
$line = getcsvline( $row, ",", "\"", "\r\n" );
fwrite( $fp, $line);

Alternativ können Sie die Ausgabe in nativen UNIX-Format (\ n nur) dann laufen unix2dos auf der resultierende Datei zu konvertieren \ r \ n an den entsprechenden Stellen. Genau darauf achten, dass Ihre Daten enthält keine \ n ist. Auch ich sehe Sie einen Standard-Separator von ~ verwenden. versuchen, einen Standard-Separator von \ t.

Wie webbiedave hingewiesen (thx!) Wahrscheinlich der sauberste Weg ist, einen Strom-Filter zu verwenden.

Es ist ein bisschen komplexer als andere Lösungen, sondern funktioniert auch auf Streams, die nicht bearbeitet werden können, nachdem (wie ein Download über $handle = fopen('php://output', 'w');), um sie zu schreiben

Hier ist mein Ansatz:

class StreamFilterNewlines extends php_user_filter {
    function filter($in, $out, &$consumed, $closing) {

        while ( $bucket = stream_bucket_make_writeable($in) ) {
            $bucket->data = preg_replace('/([^\r])\n/', "$1\r\n", $bucket->data);
            $consumed += $bucket->datalen;
            stream_bucket_append($out, $bucket);
        }
        return PSFS_PASS_ON;
    }
}

stream_filter_register("newlines", "StreamFilterNewlines");
stream_filter_append($handle, "newlines");

fputcsv($handle, $list, $seperator, $enclosure);
...

Ich habe mit einer ähnlichen Situation beschäftigt. Hier ist eine Lösung, die ich gefunden habe, dass Ausgaben CSV-Dateien mit Windows-freundlichen Zeilenende.

http://www.php.net/manual/en/ function.fputcsv.php # 90883

war ich nicht in der Lage das zu verwenden, da ich versuche, eine Datei an den Client zu streamen und kann nicht die fseeks verwenden.

Fenster muss \r\n als linebreak / Wagen Rückkehr Combo um getrennte Leitungen zu zeigen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top