Export über CSP nach CSV

Antworten:

307

Ich persönlich benutze diese Funktion, um CSV-Inhalte aus einem beliebigen Array zu erstellen.

function array2csv(array &$array)
{
   if (count($array) == 0) {
     return null;
   }
   ob_start();
   $df = fopen("php://output", 'w');
   fputcsv($df, array_keys(reset($array)));
   foreach ($array as $row) {
      fputcsv($df, $row);
   }
   fclose($df);
   return ob_get_clean();
}

Dann können Sie Ihren Benutzer dazu bringen, diese Datei herunterzuladen, indem Sie Folgendes verwenden:

function download_send_headers($filename) {
    // disable caching
    $now = gmdate("D, d M Y H:i:s");
    header("Expires: Tue, 03 Jul 2001 06:00:00 GMT");
    header("Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate");
    header("Last-Modified: {$now} GMT");

    // force download  
    header("Content-Type: application/force-download");
    header("Content-Type: application/octet-stream");
    header("Content-Type: application/download");

    // disposition / encoding on response body
    header("Content-Disposition: attachment;filename={$filename}");
    header("Content-Transfer-Encoding: binary");
}

Anwendungsbeispiel:

download_send_headers("data_export_" . date("Y-m-d") . ".csv");
echo array2csv($array);
die();
Alain Tiemblo
quelle
1
Auf dem lokalen Server funktioniert es, aber auf einem entfernten Server wird eine neue Seite mit Inhalt und ohne Download-Fenster angezeigt (Entschuldigung für mein Englisch)
khaled_webdev
2
Es kann mehrere Gründe für Fehler geben. Der einfachste Weg, sie zu finden, besteht darin, sich Ihre Apache error.log-Datei anzusehen.
Alain Tiemblo
7
Sie müssen die();gleich danach einen Anruf tätigen echo array2csv();, wird meine Antwort bearbeiten. Stellen Sie sicher, dass Sie Ihre CSV generieren, bevor Sie etwas auf Ihrer Seite ausgeben.
Alain Tiemblo
1
@ ring0 Ich denke, das Einfügen des letzten Datums in den Header deaktiviert das Seiten-Caching. Schauen Sie sich das zweite Beispiel an. php.net/manual/en/function.header.php
Abhishek Madhani
2
Gibt Ihrem Browser MIME-Typen, sodass Sie anstelle der im aktuellen Fenster gerenderten CSV ein Download-Modal erhalten.
Alain Tiemblo
32

Mit diesem Befehl können Sie das Datum exportieren.

<?php

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

$fp = fopen('file.csv', 'w');

foreach ($list as $fields) {
    fputcsv($fp, $fields);
}

fclose($fp);
?>

Zuerst müssen Sie die Daten vom MySQL-Server in ein Array laden

ynh
quelle
10
Oder Sie können fputcsv () in einer Standard-Fetch-Assoc-Schleife ausführen und direkt aus den zurückgegebenen Ergebnissen ablegen.
DampeS8N
10
@ DampeS8N, +1 für die Verwendung von "plop it down out out" in einem Satz.
AnchovyLegend
Dies wird ohne Namensnennung aus dem PHP-Handbuch für fputcsv
BenK
14

Nur für die Aufzeichnung ist die Verkettung waaaaaay schneller (ich meine es ernst) als fputcsvoder sogar implode; Und die Dateigröße ist kleiner:

// The data from Eternal Oblivion is an object, always
$values = (array) fetchDataFromEternalOblivion($userId, $limit = 1000);

// ----- fputcsv (slow)
// The code of @Alain Tiemblo is the best implementation
ob_start();
$csv = fopen("php://output", 'w');
fputcsv($csv, array_keys(reset($values)));
foreach ($values as $row) {
    fputcsv($csv, $row);
}
fclose($csv);
return ob_get_clean();

// ----- implode (slow, but file size is smaller)
$csv = implode(",", array_keys(reset($values))) . PHP_EOL;
foreach ($values as $row) {
    $csv .= '"' . implode('","', $row) . '"' . PHP_EOL;
}
return $csv;
// ----- concatenation (fast, file size is smaller)
// We can use one implode for the headers =D
$csv = implode(",", array_keys(reset($values))) . PHP_EOL;
$i = 1;
// This is less flexible, but we have more control over the formatting
foreach ($values as $row) {
    $csv .= '"' . $row['id'] . '",';
    $csv .= '"' . $row['name'] . '",';
    $csv .= '"' . date('d-m-Y', strtotime($row['date'])) . '",';
    $csv .= '"' . ($row['pet_name'] ?: '-' ) . '",';
    $csv .= PHP_EOL;
}
return $csv;

Dies ist das Ergebnis der Optimierung mehrerer Berichte von zehn auf tausend Zeilen. Die drei Beispiele funktionierten unter 1000 Zeilen einwandfrei, schlagen jedoch fehl, wenn die Daten größer waren.

Axel A. García
quelle
9

Ich empfehle parsecsv-for-php , um Probleme mit verschachtelten Zeilenumbrüchen und Anführungszeichen zu umgehen.

StigM
quelle
8

Funktioniert mit über 100 Zeilen. Wenn Sie die Größe der Datei in den Headern angeben, rufen Sie einfach die Methode get () in Ihrer eigenen Klasse auf

function setHeader($filename, $filesize)
{
    // disable caching
    $now = gmdate("D, d M Y H:i:s");
    header("Expires: Tue, 01 Jan 2001 00:00:01 GMT");
    header("Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate");
    header("Last-Modified: {$now} GMT");

    // force download  
    header("Content-Type: application/force-download");
    header("Content-Type: application/octet-stream");
    header("Content-Type: application/download");
    header('Content-Type: text/x-csv');

    // disposition / encoding on response body
    if (isset($filename) && strlen($filename) > 0)
        header("Content-Disposition: attachment;filename={$filename}");
    if (isset($filesize))
        header("Content-Length: ".$filesize);
    header("Content-Transfer-Encoding: binary");
    header("Connection: close");
}

function getSql()
{
    // return you own sql
    $sql = "SELECT id, date, params, value FROM sometable ORDER BY date;";
    return $sql;
}

function getExportData()
{
    $values = array();

    $sql = $this->getSql();
    if (strlen($sql) > 0)
    {
        $result = dbquery($sql); // opens the database and executes the sql ... make your own ;-) 
        $fromDb = mysql_fetch_assoc($result);
        if ($fromDb !== false)
        {
            while ($fromDb)
            {
                $values[] = $fromDb;
                $fromDb = mysql_fetch_assoc($result);
            }
        }
    }
    return $values;
}

function get()
{
    $values = $this->getExportData(); // values as array 
    $csv = tmpfile();

    $bFirstRowHeader = true;
    foreach ($values as $row) 
    {
        if ($bFirstRowHeader)
        {
            fputcsv($csv, array_keys($row));
            $bFirstRowHeader = false;
        }

        fputcsv($csv, array_values($row));
    }

    rewind($csv);

    $filename = "export_".date("Y-m-d").".csv";

    $fstat = fstat($csv);
    $this->setHeader($filename, $fstat['size']);

    fpassthru($csv);
    fclose($csv);
}
Bernhard Leichtle
quelle
6

Genau wie @ Dampes8N sagte:

$result = mysql_query($sql,$conecction);
$fp = fopen('file.csv', 'w');
while($row = mysql_fetch_assoc($result)){
    fputcsv($fp, $row);
}
fclose($fp);

Hoffe das hilft.

Wurzeln
quelle