Wie lade ich eine CSV-Datei von der Funktion im WordPress-Plugin herunter?

Lesezeit: 2 Minuten

Benutzeravatar von mickburkejnr
Mickburkejnr

Ich habe ein Plugin für einen Kunden erstellt, damit er Daten als CSV-Datei herunterladen kann. Es wurde so eingerichtet, dass die CSV-Datei einfach automatisch heruntergeladen wird, wenn der Benutzer auf einen Link im Menü klickt. Allerdings funktioniert das nicht ganz so und lädt die Funktion einfach als Seite in das WordPress-Backend.

Dies ist der Code, den ich für die Funktion habe:

function download_payment_csv() {
    include 'lib/connection.php';

    $csv_output="";

    $values = $db->query('SELECT * FROM tbPayments ORDER BY date DESC');

    $i=0;

    while ($rowr = mysql_fetch_row($values)) {
        for ($j=0;$j<$i;$j++) {
            $csv_output .= $rowr[$j].",";
        }
        $csv_output .= "\n";
    }

    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: private", false);
    header("Content-Type: application/octet-stream");
    header("Content-Disposition: attachment; filename=\"report.csv\";" );
    header("Content-Transfer-Encoding: binary");

    echo $csv_output;

}

Und wie gesagt, es gibt nur einen leeren Bildschirm zurück. Jede Hilfe wäre willkommen!

BEARBEITEN
Das ist also der Code, mit dem ich jetzt arbeite, indem ich Teile von dem nehme, was bereits gesagt wurde.

function download_payment_csv() {

    include 'lib/connection.php';

    $csv_output="";

    $values = load_payment_csv();

    $fp = fopen("php://output", "w");

    $file="test_export";
    $filename = $file."_".date("Y-m-d_H-i",time());
    header("Content-Type: text/csv");
    header("Content-Disposition: attachment; filename=".$filename.".csv");
    // Disable caching
    header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP 1.1
    header("Pragma: no-cache"); // HTTP 1.0
    header("Expires: 0"); // Proxies
    header("Content-Transfer-Encoding: UTF-8");

    if(count($values) > 0) {
        foreach($values as $result) {
            fputcsv($fp, $result);
        }
    }

    fclose($fp);

}

Dadurch wird eine CSV-Datei generiert, aber es gibt ein Problem damit. Das Problem besteht darin, dass beim Anzeigen der Seite diese nicht als CSV heruntergeladen wird, sondern nur der Inhalt der CSV-Datei auf der Seite ausgegeben wird. Fügen Sie diese Funktion jedoch oben im Plugin hinzu:

add_action('admin_init','download_payment_csv');

Dies löst dann einen Download aus, wenn auf den Menülink geklickt wird, was in Ordnung ist. Aber es löst es für jeden Menüpunkt im Plugin aus, was falsch ist. Es sollte nur ausgelöst werden, wenn auf den Download-Link geklickt wird.

  • wenn du nur echost $csv_output ; bekommst du eine ausgabe?

    – Mudaser Ali

    18. August 2015 um 8:27 Uhr

  • Wenn es nur als Funktion geladen wird, enthält es eine Ausgabe? Ebenfalls Verwenden Sie nicht mysql_, verwenden Sie PDO oder mysqli_

    – Justinas

    18. August 2015 um 8:31 Uhr

  • Ich bekomme absolut keine Ausgabe, wenn ich nur $csv_output echoe, wenn es nur als Funktion geladen wird

    – Mickburkejnr

    18. August 2015 um 8:37 Uhr

  • Es scheint, dass Sie $i niemals etwas anderem als 0 zuweisen, daher wird die for-Schleife niemals ausgeführt, da $j<$i (was 0 ist) - und nur die \n-Symbole hinzugefügt werden

    – Lemur

    18. August 2015 um 8:42 Uhr


/** * Abfrage der obersten Titelzeile */

$results = $wpdb->get_results("SHOW COLUMNS FROM $table" );
if(count($results) > 0){
    foreach($results as $result){
        $csv_output .= str_replace('_',' ',$result->Field).", "; // , or ;      
    }
}
$csv_output .= "\n";

/** * Alle erforderlichen Daten abfragen */

$results = $wpdb->get_results("SELECT * FROM $table",ARRAY_A );
if(count($results) > 0){
    foreach($results as $result){
        $result = array_values($result);
        $result = implode(", ", $result);
        $csv_output .= $result."\n"; 
    }
}

/** * Dateinamen und CSV-Datei für den Export vorbereiten */

$filename = $file."_".date("Y-m-d_H-i",time());
header("Content-type: application/vnd.ms-excel");
header("Content-disposition: csv" . date("Y-m-d") . ".csv");
header( "Content-disposition: filename=".$filename.".csv");
print $csv_output;
exit;

Dies alles in eine Funktion zu packen, sollte ausreichen

  • Das ist ein toller Typ 🙂

    – Blaue Rose

    21. August 2015 um 3:05 Uhr

  • Das ist gut, aber ich erhalte Fehlermeldungen, die besagen, dass die Header-Informationen nicht geändert werden können?

    – Mickburkejnr

    21. August 2015 um 11:20 Uhr

Benutzeravatar von Prakash Madhak
Prakash Madhak

Versuche dies:

<?php

class CSVExport
{
/**
 * Constructor
 */
public function __construct()
{
    if(isset($_GET['download_report']))
    {
        $csv = $this->generate_csv();

        header("Pragma: public");
        header("Expires: 0");
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Cache-Control: private", false);
        header("Content-Type: application/octet-stream");
        header("Content-Disposition: attachment; filename=\"report.csv\";" );
        header("Content-Transfer-Encoding: binary");

        echo $csv;
        exit;
    }

    // Add extra menu items for admins
    add_action('admin_menu', array($this, 'admin_menu'));

    // Create end-points
    add_filter('query_vars', array($this, 'query_vars'));
    add_action('parse_request', array($this, 'parse_request'));
}

/**
 * Add extra menu items for admins
 */
public function admin_menu()
{
    add_menu_page('Download Report', 'Download Report', 'manage_options', 'download_report', array($this, 'download_report'));
}

/**
 * Allow for custom query variables
 */
public function query_vars($query_vars)
{
    $query_vars[] = 'download_report';
    return $query_vars;
}

/**
 * Parse the request
 */
public function parse_request(&$wp)
{
    if(array_key_exists('download_report', $wp->query_vars))
    {
        $this->download_report();
        exit;
    }
}

/**
 * Download report
 */
public function download_report()
{
    echo '<div class="wrap">';
    echo '<div id="icon-tools" class="icon32"></div>';
    echo '<h2>Download Report</h2>';
    //$url = site_url();

    echo '<p><a href="https://stackoverflow.com/questions/32012440/site_url()/wp-admin/admin.php?page=download_report&download_report">Export the Subscribers</a>';
}

/**
 * Converting data to CSV
 */
public function generate_csv()
{
    $csv_output="";
    $table="users";

    $result = mysql_query("SHOW COLUMNS FROM ".$table."");

    $i = 0;
    if (mysql_num_rows($result) > 0) {
        while ($row = mysql_fetch_assoc($result)) {
            $csv_output = $csv_output . $row['Field'].",";
            $i++;
        }
    }
    $csv_output .= "\n";

    $values = mysql_query("SELECT * FROM ".$table."");
    while ($rowr = mysql_fetch_row($values)) {
        for ($j=0;$j<$i;$j++) {
            $csv_output .= $rowr[$j].",";
        }
        $csv_output .= "\n";
    }

    return $csv_output;
}
}

// Instantiate a singleton of this plugin
$csvExport = new CSVExport();

  • Ziemlich großes Sicherheitsproblem hier … jeder kann den Bericht herunterladen, indem er einfach rät download_report Parameter…

    – Mikk3lRo

    22. August 2015 um 20:33 Uhr

Benutzeravatar von Hans Koch
Hans Koch

Sie müssen einige Header-Informationen ändern

header('Content-Type: text/csv');
header('Content-Disposition: attachment;filename="report.csv"');
header('Cache-Control: max-age=0');
// If you're serving to IE 9, then the following may be needed
header('Cache-Control: max-age=1');
// If you're serving to IE over SSL, then the following may be needed
header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified
header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1
header ('Pragma: public'); // HTTP/1.0

Verwenden Sie danach php://output, um die Daten direkt an den Browser zu liefern, dies verhindert die leere Seite.

zum Beispiel:

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

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

fclose($outstream);
exit();

php://output ist ein schreibgeschützter Stream, mit dem Sie Daten direkt an den Anforderer senden können.

EDIT: Auch sollten Sie $wpdb verwenden

  • Dies gibt immer noch HTML-Code am Anfang der Datei in einer Front-Side-Wordpress-Umgebung aus

    – Debbie Kurth

    2. März 2021 um 22:21 Uhr

  • Sie rufen dies in Ihrer Vorlage auf. Dies soll von einer GET-Anforderung aufgerufen werden, die nicht mit Ihrer Vorlage verknüpft ist.

    – Hans Koch

    15. April 2021 um 0:23 Uhr

  • Könnte ein bisschen spät für @DebbieKurth sein, aber füge hinzu ob_end_clean();Place, ob_end_clean(); before you output the csv. "Clean (erase) the output buffer and turn off output buffering" - PHP manual.

    – Taorich

    23. Juni um 15:37 Uhr

Hier ist die Lösung, die ich gefunden habe, nachdem ich jede Menge Probleme mit der Ausgabe von HTML-Code hatte, wenn er auf der Vorderseite der Website verwendet wurde. Der Schlüssel ist, exit gegen ‘sterben’ auszutauschen. Dies ist der Code, den ich auf meinen eigenen Seiten verwende.


header('Content-Type: text/csv');
$FileName="Content-Disposition: attachment; filename="". 'Report.csv"';
header($FileName);

$fp = fopen('php://output', 'w');
    
$header_row = array(
        0 => 'data1',
        1 => 'data2',
        2 => 'data3',
    );
fputcsv($fp, $header_row); 

$rows = GetDataBaseData();
if(!empty($rows)) 
  {
   foreach($rows as $Record)
     {      
    // where data1, data2, data3 are the database column names 
    $OutputRecord = array($Record['data1'], $Record['data1'], $Record['data1']);
    fputcsv($fp, $OutputRecord);         
    }
    unset($rows);
  }

fclose( $fp );
    
die;   <===== key point.  Use DIE not Exit.  Exit will only work on the back end. Die will work on both.
```

Works on the front and backend of wordpress.    

1401300cookie-checkWie lade ich eine CSV-Datei von der Funktion im WordPress-Plugin herunter?

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

Privacy policy