Erstellen Sie eine CSV-Datei für einen Benutzer in PHP

220

Ich habe Daten in einer MySQL-Datenbank. Ich sende dem Benutzer eine URL, um seine Daten als CSV-Datei zu erhalten.

Ich habe das E-Mail-Versenden des Links, der MySQL-Abfrage usw. abgedeckt.

Wie kann ich, wenn sie auf den Link klicken, ein Popup haben, um ein CVS mit dem Datensatz von MySQL herunterzuladen?

Ich habe alle Informationen, um die Aufzeichnung bereits zu erhalten. Ich sehe nur nicht, wie PHP die CSV-Datei erstellen und sie eine Datei mit der Erweiterung .csv herunterladen lassen soll.

d -_- b
quelle

Antworten:

280

Versuchen:

header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=file.csv");
header("Pragma: no-cache");
header("Expires: 0");

echo "record1,record2,record3\n";
die;

etc

Bearbeiten: Hier ist ein Codeausschnitt, mit dem ich optional CSV-Felder codiere:

function maybeEncodeCSVField($string) {
    if(strpos($string, ',') !== false || strpos($string, '"') !== false || strpos($string, "\n") !== false) {
        $string = '"' . str_replace('"', '""', $string) . '"';
    }
    return $string;
}
Oleg Barshay
quelle
11
Beachten Sie, dass die Regeln für CSVs wichtig sind. Um eine gute Anzeige zu gewährleisten, setzen Sie doppelte Anführungszeichen um Ihre Felder und vergessen Sie nicht, doppelte Anführungszeichen in Feldern durch doppelte doppelte Anführungszeichen zu ersetzen: "echo" ".str_replace (" "," ", $ record1). '","'. str_replace ....
Mala
46
Zur Verdeutlichung lautet der korrekte HTTP-Content-Type-Header für CSV text / csv, nicht application / csv. Ich bezweifle, dass es einem modernen Browser so oder so etwas ausmacht, aber da es Standards gibt, können wir sie genauso gut verwenden.
Fentie
10
Befolgen Sie im Allgemeinen RFC 4180, wenn Sie CSV-Dateien generieren. tools.ietf.org/html/rfc4180
Oleg Barshay
5
@Oleg Barshay: OMG, dieser RFC ist ein Meisterwerk: "Wenn doppelte Anführungszeichen zum Einschließen von Feldern verwendet werden, muss ein doppeltes Anführungszeichen, das in einem Feld erscheint, durch ein weiteres doppeltes Anführungszeichen maskiert werden." EIN ANDERES DOPPELZITAT!
Aefxx
465
header("Content-Type: text/csv");
header("Content-Disposition: attachment; filename=file.csv");

function outputCSV($data) {
  $output = fopen("php://output", "wb");
  foreach ($data as $row)
    fputcsv($output, $row); // here you can change delimiter/enclosure
  fclose($output);
}

outputCSV(array(
  array("name 1", "age 1", "city 1"),
  array("name 2", "age 2", "city 2"),
  array("name 3", "age 3", "city 3")
));

php: // fputcsv ausgeben

Andrii Nemchenko
quelle
64
Mehr Menschen müssen dies sehen und abstimmen. Dies ist mit Sicherheit die beste Antwort auf dieser Seite. PHP verfügt bereits über integrierte Funktionen zum Formatieren von CSV-Inhalten. Jeder sollte sie benutzen. Tolle Antwort, @Andrey :)
Maček
2
Schade, dass fputcsv () nicht richtig funktioniert :( bugs.php.net/bug.php?id=50686
gou1
4
Schön, aber die outputCSVFunktion ist unnötig kompliziert. Sie können einfach foreachvorbei $arrayund seine Werte direkt in senden fputcsv. Keine Notwendigkeit dafür __outputCSVund das array_walk:)foreach($data as $vals) {fputcsv($filehandler,$vals);}
Sygmoral
Ich habe einige Probleme mit französischen Zeichen im Array, da die CSV-Datei möglicherweise in Excel geöffnet sein muss. Es verschluckt sich an den akzentuierten Zeichen. Dinge wie "Prévalence","age 1","city 1" Irgendwelche Ideen? Das Spielen mit UTF-8 hat bisher nicht geholfen.
Voodoo
1
@theosem Delimiter hängt von den Exporteinstellungen des Betriebssystems oder Excel ab. Ich habe einen Hinweis zum Trennzeichen hinzugefügt.
Andrii Nemchenko
19

Hier ist eine verbesserte Version der Funktion von php.net, die @Andrew veröffentlicht hat.

function download_csv_results($results, $name = NULL)
{
    if( ! $name)
    {
        $name = md5(uniqid() . microtime(TRUE) . mt_rand()). '.csv';
    }

    header('Content-Type: text/csv');
    header('Content-Disposition: attachment; filename='. $name);
    header('Pragma: no-cache');
    header("Expires: 0");

    $outstream = fopen("php://output", "wb");

    foreach($results as $result)
    {
        fputcsv($outstream, $result);
    }

    fclose($outstream);
}

Es ist sehr einfach zu bedienen und funktioniert hervorragend mit MySQL (i) / PDO-Ergebnismengen.

download_csv_results($results, 'your_name_here.csv');

Denken exit()Sie daran, nachdem Sie dies aufgerufen haben, wenn Sie mit der Seite fertig sind.

Xeoncross
quelle
Wie ändern Sie das Trennzeichen von, nach; ?
Mürrisch
1
Wie sollen wir eine Schaltfläche hinzufügen, um dieses Ereignis auszulösen, damit der Benutzer die CSV-Datei bei Bedarf herunterladen kann?
CanCeylan
Ich werde "SyntaxError: Unerwartetes Token ILLEGAL" Fehler mit der Zeile "fopen (" php: // output "," w ");" Wenn ich es in "$ fp = fopen ('stats.csv', 'w');" ändere; Es wird kein Fehler angezeigt. Aber dann funktioniert es natürlich nicht. Wie soll ich das lösen?
CanCeylan
@CanCeylan, das ist eine Frage für sich und ich brauche mehr Details, um sie zu lösen.
Xeoncross
1
Fügen Sie fputcsv($outstream, array_keys($results[0]));kurz vor Ihrem hinzu, foreachum auch Spaltenüberschriften einzuschließen.
Justin
16

Zusätzlich zu allem, was bereits gesagt wurde, müssen Sie möglicherweise Folgendes hinzufügen:

header("Content-Transfer-Encoding: UTF-8");

Dies ist sehr nützlich, wenn Sie Dateien mit mehreren Sprachen verarbeiten, z. B. Namen von Personen oder Städte.

Stan
quelle
9

Der Thread ist ein wenig alt, ich weiß, aber als zukünftige Referenz und für Noobs wie mich:

Alle anderen hier erklären, wie man die CSV erstellt, verpassen jedoch einen grundlegenden Teil der Frage: wie man sie verknüpft. Um einen Link zum Download der CSV-Datei zu erstellen, verlinken Sie einfach auf die PHP-Datei, die wiederum als CSV-Datei reagiert. Die PHP-Header machen das. Dies ermöglicht coole Dinge wie das Hinzufügen von Variablen zum Querystring und das Anpassen der Ausgabe:

<a href="my_csv_creator.php?user=23&amp;othervariable=true">Get CSV</a>

my_csv_creator.php kann mit den im Abfragering angegebenen Variablen arbeiten und beispielsweise verschiedene oder angepasste Datenbankabfragen verwenden, die Spalten der CSV ändern, den Dateinamen personalisieren usw., z.

User_John_Doe_10_Dec_11.csv
LBJ
quelle
1
Äh - jeder, der dies liest, ist SEHR vorsichtig mit diesem Ansatz. Ich würde wetten, dass Eingaben nicht ordnungsgemäß maskiert werden und dies zu großen Sicherheitslücken in Ihrer Anwendung führen kann.
Calumbrodie
Seine Methode ist sehr sicher und funktioniert hervorragend. Sie können den Zugriff mit der Sitzung einfach steuern und alle Informationen, die Sie in eine CSV einfügen möchten, in einer Sitzungsvariablen speichern. Deaktivieren Sie es dann einfach als Teil des Konvertierungsprozesses in eine CSV. Ich würde nur vorschlagen, Sitzungsvariablen anstelle einer Abfragezeichenfolge zu verwenden.
anorganik
1
Bei dieser Methode gibt es an sich keine Sicherheitslücken. Solange die PHP-Datei, auf die verwiesen wird, die Hygiene und Zugriffsprüfung übernimmt. Aber es macht nicht wirklich Sinn, das alles hier zu zeigen. Der Punkt des Beitrags ist, dass Sie auf die URL verlinken können, die die CSV generiert.
Danielson317
8

Erstellen Sie Ihre Datei und geben Sie einen Verweis mit dem richtigen Header zurück, um das Speichern unter auszulösen. Bearbeiten Sie Folgendes nach Bedarf. Fügen Sie Ihre CSV-Daten in $ csvdata ein.

$fname = 'myCSV.csv';
$fp = fopen($fname,'wb');
fwrite($fp,$csvdata);
fclose($fp);

header('Content-type: application/csv');
header("Content-Disposition: inline; filename=".$fname);
readfile($fname);
typemismatch
quelle
1
Die Verwendung von "Inline" -Inhaltsdisposition bedeutet, dass der Browser versuchen sollte, sie ohne Download anzuzeigen (IE neigt dazu, eine Excel-Instanz dafür einzubetten). "Anhang" ist erforderlich, um einen Download zu erzwingen.
Gert van den Berg
5

Hier ist ein voll funktionsfähiges Beispiel mit PDO und Spaltenüberschriften:

$query = $pdo->prepare('SELECT * FROM test WHERE id=?');
$query->execute(array($id));    
$results = $query->fetchAll(PDO::FETCH_ASSOC);
download_csv_results($results, 'test.csv'); 
exit();


function download_csv_results($results, $name)
{            
    header('Content-Type: text/csv');
    header('Content-Disposition: attachment; filename='. $name);
    header('Pragma: no-cache');
    header("Expires: 0");

    $outstream = fopen("php://output", "wb");    
    fputcsv($outstream, array_keys($results[0]));

    foreach($results as $result)
    {
        fputcsv($outstream, $result);
    }

    fclose($outstream);
}
Justin
quelle
4

Machen Sie zuerst Daten als String mit Komma als Trennzeichen (getrennt durch ","). Etwas wie das

$CSV_string="No,Date,Email,Sender Name,Sender Email \n"; //making string, So "\n" is used for newLine

$rand = rand(1,50); //Make a random int number between 1 to 50.
$file ="export/export".$rand.".csv"; //For avoiding cache in the client and on the server 
                                     //side it is recommended that the file name be different.

file_put_contents($file,$CSV_string);

/* Or try this code if $CSV_string is an array
    fh =fopen($file, 'w');
    fputcsv($fh , $CSV_string , ","  , "\n" ); // "," is delimiter // "\n" is new line.
    fclose($fh);
*/
Behzad Ravanbakhsh
quelle
3

Hey es funktioniert sehr gut .... !!!! Vielen Dank an Peter Mortensen und Connor Burton

<?php
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=file.csv");
header("Pragma: no-cache");
header("Expires: 0");

ini_set('display_errors',1);
$private=1;
error_reporting(E_ALL ^ E_NOTICE);

mysql_connect("localhost", "user", "pass") or die(mysql_error());
mysql_select_db("db") or die(mysql_error());

$start = $_GET["start"];
$end = $_GET["end"];

$query = "SELECT * FROM customers WHERE created>='{$start} 00:00:00'  AND created<='{$end} 23:59:59'   ORDER BY id";
$select_c = mysql_query($query) or die(mysql_error());

while ($row = mysql_fetch_array($select_c, MYSQL_ASSOC))
{
    $result.="{$row['email']},";
    $result.="\n";
    echo $result;
}

?>

Kaddy
quelle
Sie NICHT diesen Code in der Produktion verwenden, ist es anfällig für SQL - Injektionen
ntzm
2

Einfache Methode -

$data = array (
    'aaa,bbb,ccc,dddd',
    '123,456,789',
    '"aaa","bbb"');

$fp = fopen('data.csv', 'wb');
foreach($data as $line){
    $val = explode(",",$line);
    fputcsv($fp, $val);
}
fclose($fp);

Jede Zeile des $dataArrays wird also in eine neue Zeile Ihrer neu erstellten CSV-Datei verschoben. Es funktioniert nur für PHP 5 und höher.

user244641
quelle
2

Sie können Ihre Daten einfach mit in CSV schreiben Funktion fputcsv schreiben . Schauen wir uns das folgende Beispiel an. Schreiben Sie das Listenarray in die CSV-Datei

$list[] = array("Cars", "Planes", "Ships");
$list[] = array("Car's2", "Planes2", "Ships2");
//define headers for CSV 
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=file_name.csv');
//write data into CSV
$fp = fopen('php://output', 'wb');
//convert data to UTF-8 
fprintf($fp, chr(0xEF).chr(0xBB).chr(0xBF));
foreach ($list as $line) {
    fputcsv($fp, $line);
}
fclose($fp);
Shahbaz
quelle
1

Am einfachsten ist es, eine dedizierte CSV-Klasse wie die folgende zu verwenden:

$csv = new csv();
$csv->load_data(array(
    array('name'=>'John', 'age'=>35),
    array('name'=>'Adrian', 'age'=>23), 
    array('name'=>'William', 'age'=>57) 
));
$csv->send_file('age.csv'); 
Sergiu
quelle
1

Anstatt:

$query = "SELECT * FROM customers WHERE created>='{$start} 00:00:00'  AND created<='{$end} 23:59:59'   ORDER BY id";
$select_c = mysql_query($query) or die(mysql_error()); 

while ($row = mysql_fetch_array($select_c, MYSQL_ASSOC))
{
    $result.="{$row['email']},";
    $result.="\n";
    echo $result;
}

Verwenden:

$query = "SELECT * FROM customers WHERE created>='{$start} 00:00:00'  AND created<='{$end} 23:59:59'   ORDER BY id";
$select_c = mysql_query($query) or die(mysql_error()); 

while ($row = mysql_fetch_array($select_c, MYSQL_ASSOC))
{
    echo implode(",", $row)."\n";
}
Joshua
quelle
1

Es kam bereits eine sehr gute Lösung. Ich gebe nur den Gesamtcode ein, damit ein Neuling die totale Hilfe bekommt

<?php
extract($_GET); //you can send some parameter by query variable. I have sent table name in *table* variable

header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=$table.csv");
header("Pragma: no-cache");
header("Expires: 0");

require_once("includes/functions.php"); //necessary mysql connection functions here

//first of all I'll get the column name to put title of csv file.
$query = "SHOW columns FROM $table";
$headers = mysql_query($query) or die(mysql_error());
$csv_head = array();
while ($row = mysql_fetch_array($headers, MYSQL_ASSOC))
{
    $csv_head[] =  $row['Field'];
}
echo implode(",", $csv_head)."\n";

//now I'll bring the data.
$query = "SELECT * FROM $table";
$select_c = mysql_query($query) or die(mysql_error()); 

while ($row = mysql_fetch_array($select_c, MYSQL_ASSOC))
{
    foreach ($row as $key => $value) {
            //there may be separator (here I have used comma) inside data. So need to put double quote around such data.
        if(strpos($value, ',') !== false || strpos($value, '"') !== false || strpos($value, "\n") !== false) {
            $row[$key] = '"' . str_replace('"', '""', $value) . '"';
        }
    }
    echo implode(",", $row)."\n";
}

?>

Ich habe diesen Code in csv-download.php gespeichert

Nun sehen Sie, wie ich diese Daten zum Herunterladen der CSV-Datei verwendet habe

<a href="csv-download.php?table=tbl_vfm"><img title="Download as Excel" src="images/Excel-logo.gif" alt="Download as Excel" /><a/>

Wenn ich auf den Link geklickt habe, wird die Datei heruntergeladen, ohne dass ich im Browser zur Seite csv-download.php weitergeleitet werde.

zahid9i
quelle
0

Verwenden Sie header (), damit es als CSV gesendet und der Dateiname angegeben wird:

http://us2.php.net/header

header('Content-type: text/csv');
header('Content-disposition: attachment; filename="myfile.csv"');

Wenn Sie die CSV selbst erstellen möchten, durchlaufen Sie einfach die Ergebnismenge, formatieren die Ausgabe und senden sie wie alle anderen Inhalte.

Gavin M. Roy
quelle
0

Das Schreiben Ihres eigenen CSV-Codes ist wahrscheinlich Zeitverschwendung. Verwenden Sie einfach ein Paket wie League / CSV - es behandelt alle schwierigen Dinge für Sie, die Dokumentation ist gut und es ist sehr stabil / zuverlässig:

http://csv.thephpleague.com/

Sie müssen Composer verwenden. Wenn Sie nicht wissen, was ein Komponist ist, empfehle ich Ihnen dringend, einen Blick darauf zu werfen: https://getcomposer.org/

John Hunt
quelle
0
<?
    // Connect to database
    $result = mysql_query("select id
    from tablename
    where shid=3");
    list($DBshid) = mysql_fetch_row($result);

    /***********************************
    Write date to CSV file
    ***********************************/

    $_file = 'show.csv';
    $_fp = @fopen( $_file, 'wb' );

    $result = mysql_query("select name,compname,job_title,email_add,phone,url from UserTables where id=3");

    while (list( $Username, $Useremail_add, $Userphone, $Userurl) = mysql_fetch_row($result))
    {
        $_csv_data = $Username.','.$Useremail_add.','.$Userphone.','.$Userurl . "\n";
        @fwrite( $_fp, $_csv_data);
    }
    @fclose( $_fp );
?>
Vish00722
quelle
0

Wie schreibe ich in eine CSV-Datei mit einem PHP-Skript? Eigentlich habe ich auch danach gesucht. Mit PHP ist das eine leichte Aufgabe. fputs (Handler, Inhalt) - diese Funktion arbeitet für mich effizient. Zuerst müssen Sie die Datei, in die Sie Inhalte schreiben müssen, mit fopen ($ CSVFileName, 'wb') öffnen.

$CSVFileName = test.csv”;
$fp = fopen($CSVFileName, wb’);

//Multiple iterations to append the data using function fputs()
foreach ($csv_post as $temp)
{
    $line = “”;
    $line .= Content 1 . $comma . $temp . $comma . Content 2 . $comma . 16/10/2012″.$comma;
    $line .= \n”;
    fputs($fp, $line);
}
ntzm
quelle
Es wird immer bevorzugt, den Code selbst hinzuzufügen, anstatt ihn zu verknüpfen, da sich die Links im Laufe der Zeit ändern oder verschwinden.
Sgoettschkes
Ihre Antwort ist auf einen sehr alten Thread. Während es 2008 üblich war, eigene durch Kommas getrennte Zeilen zu erstellen, bestand die richtige Methode seit PHP 5.1.0 darin, die integrierte Funktion fputcsv ( php.net/fputcsv ) zu verwenden. Achten Sie beim Lesen alter Threads darauf, dass die darin enthaltenen Informationen weiterhin relevant sind.
Luke Mills
-1

Geben Sie $outputdie CSV-Daten in die Variable ein und geben Sie die richtigen Überschriften ein

header("Content-type: application/download\r\n");
header("Content-disposition: filename=filename.csv\r\n\r\n");
header("Content-Transfer-Encoding: ASCII\r\n");
header("Content-length: ".strlen($output)."\r\n");
echo $output;
Lorenzo Massacci
quelle