Download CSV file with PHP using Wordpress

wordpress export database table to csv
how to export csv file in wordpress
wp_list_table export csv
wordpress export database table to csv plugin
wordpress export plugin
export wordpress categories to excel
wordpress export users to csv without plugin
php export to csv

I have developed a little plugin (for training) for Wordpress. The plugin allows to get the data from a form, save it into a csv file, and then the admin can download the file.

My problem is that I can't download this file. When I click on the download button, it opens a download.php page but nothing more happens.

I tried different solutions but nothing is working. Here is the code of the main file:

    Plugin Name: Form to CSV
    Version: 1.0
    Author: Grégory Huyghe

// 1. Shortcode
function ftc_shortcode() {
    readfile("form-to-csv.html", 1);

add_shortcode( 'form_csv', 'ftc_shortcode' );

// 1.1 CSS
function ftc_style() {
    wp_register_style('stylesheet', plugins_url('form-to-csv.css', __FILE__));

add_action('admin_init', 'ftc_style');

// 2. Onglet plugin dans panneau admin pour voir et télécharger les données collectées
function ftc_menu_item() {
        __( 'Form to CSV', 'textdomain' ),
        'Form to CSV',
add_action('admin_menu', 'ftc_menu_item');

// 3. Ecrire les données dans un fichier

// 3.1 Variables
$error = '';
$fname = sanitize_text_field($_POST['prenom']);
$lname = sanitize_text_field($_POST['nom']);
$email = sanitize_email($_POST['email']);
$checkbox = implode(" / ", (array)$_POST['films']);

// 3.2 Clean_text
function clean_text($clean) {
    $trimmed = trim($clean);
    $stripped = stripslashes($clean);
    $special = htmlspecialchars($clean);
    return $clean;

// 3.3 Submission form
if(isset($_POST['submit'])) {
    $success = true;

    if(empty($_POST['prenom']) OR empty($_POST['nom']) OR empty($_POST['email'])) {
        $error = '<p>Veuillez réessayer</p>';
    } else {
        $fname = clean_text($_POST['prenom']);
        $lname = clean_text($_POST['nom']);
        $email = clean_text($_POST['email']);

    if($error == '' && $success = true) {

        // Ecriture dans fichier csv
        $file_open = fopen('C:\Users\huygh\Desktop\form-to-csv.csv', 'a');
        $index = count(file('C:\Users\huygh\Desktop\form-to-csv.csv')); 
        if ($index == 0) {
            $index = $index +1;
        } else if ($index > 0) {
            $index = $index +1;

        $form_data = array(
        'id' => $index,
        'prenom' => $fname,
        'nom' => $lname,
        'email' => $email,
        'films' => $checkbox
        fputcsv($file_open, $form_data);
        header( 'Location: index.php' );

// 4. Récupérer ses infos dans un custom post accessible depuis le panneau admin. Pas d'envoi de mail.

// 4.1 Récupérer et  Afficher les données dans l'onglet du plugin

function ftc_menu_plugin() {

//    if (isset($_GET['action']) && $_GET['action'] == 'download') {
//        header('Location: C:\Users\huygh\Desktop\form-to-csv.csv');
//        header('Content-Disposition: attachment; filename="form-to-csv.csv"');
//        header("Content-Type: application/force-download");
//        header("Content-Transfer-Encoding: Binary");
//        header("Pragma: no-cache");
//        header("Expires: 0");
//        readfile('form-to-csv.csv');
//        echo "toto";
//    }

    $counter = 0;

    echo "<html><body><table>\n\n";

    // Titres du tableau
    echo "<thead>";
    echo "<tr class=\"titles\">";
    echo "<th>ID</th>";
    echo "<th>Prénom</th>";
    echo "<th>Nom</th>";
    echo "<th>Email</th>";
    echo "<th>Sélection</th>";
    echo "</tr>\n";
    echo "</thead>";

    if (($file_read = fopen('C:\Users\huygh\Desktop\form-to-csv.csv', 'r')) !== FALSE) {
        while (($data = fgetcsv($file_read)) !== FALSE && $counter < 20) {
            echo "<tr>";
            foreach ($data as $cell) {
                    echo "<td>" . $cell . "</td>";
            echo "</tr>\n";
    echo "\n</table></body></html>";

    // 4.2 Télécharger ce fichier .csv depuis l'onglet du plugin

        <a href="download.php" target="_blank">
            <button class="button__csv">Télécharger fichier CSV</button>

        <a href="delete.php" target="blank">
            <button class="button__csv button__csv--delete">Supprimer données</button> 

And the code of the download.php:

header('Content-Disposition: attachment; filename="form-to-csv.csv"');
header('Content-Type: text/csv');

As you can see in the main file code, I also tried a solution without using a download.php page, writing the a tag as follow:

<a href="?action=download" target="blank">

But nothing is working. Does the problem come from the headers? Or from Wordpress, something specific to write?

Here is the screenshot of the response header in the developer tool:

As mentioned by Jamie_D, using Location will forward the user to the specified address (like in your 3.3 Submission form code block).

Remove the line from your code block and you should get the desired download page:

header('Content-Disposition: attachment; filename="form-to-csv.csv"');
header('Content-Type: text/csv');
// take care to escape the backslashes properly:

Additional comments regarding your code:

  1. Missing underscore in anchor; it should be: <a href="download.php" target="_blank">Link</a>

  2. Get rid of the closing ?php> tag: I have seen cases where control / invisible characters after the closing tag caused download troubles as they are then transmitted as part of the file's content.


In the question asker's case the problem was not due to incorrect headers sent to the client but the path pointing to the download.php was incorrect.

Create a CSV File of WordPress User Information with PHP, You may want to change which fields are downloaded from WordPress. To do this, just change the field names in the fields array to match the fields in the user  And you can use it like this: array_to_csv_download(array( array(1,2,3,4), // this array is going to be the first row array(1,2,3,4)), // this array is going to be the second row "numbers.csv" ); Update: Instead of the php://memory you can also use the php://output for the file descriptor and do away with the seeking and such:

Here is the solution, a simple mistake about the location of download.php which has to be in the wp-admin folder.

To keep the download.php file into the plugin folder, I wrote a relative URL for the a tag:

<a href="/Plugin/wp-content/plugins/form-to-csv/download.php"

Answer of SaschaM78: As you can see the "download.php" can not be found, a 404 means "Page not found". Make sure that the file really is in "plugins/wp-admin". – SaschaM78 54 mins ago

WordPress: Export custom data to CSV · GitHub, <?php. /**. * Export Data to CSV file. * Could be used in WordPress plugin or theme. */. // A sample link to Download CSV, could be placed somewhere in plugin  Sellect all options and download CSV file. This plugin has been tested and works with PHP versions 5.4 and greater. WordPress itself recommends using PHP version 7.3 or greater. If you’re using a PHP version lower than 5.4 please upgrade your PHP version or contact your Server administrator.

You can use the download property of HTML5 to down load file directly,

<a href="C:\\Users\\huygh\\Desktop\\form-to-csv.csv" download="form-to-csv.csv">download form-to-csv.csv</a>

Exporting data to csv in WordPress with PHP, In WordPress plugin development, sometimes you may need to export data to a csv file. Here  The WP Ultimate CSV Importer plugin allows you to import custom posts and WordPress Custom Fields from a CSV file into your WordPress site.. Using the WP Ultimate CSV Importer Pro plugin you will be able to import also the Types Custom Fields, which are the fields you created using the Toolset Types plugin.

export csv functionality into my plugin, The start of what you're doing wrong can be explained by this quote: which action attribute points to a file (download.csv.php) in my plugin  Export Data to CSV and Download Using PHP and MySQL Last Updated On: October 22, 2017 October 22, 2017 | By: Parvez In previous tutorial we have learn How To Export Data to Excel ,here in this article we will learn how to export data into CSV (comma-separated values) file and download it, CSV is a very common format for transferring tabular

CSV export of WordPress data, For more complex queries, I use PHP to do some of the heavy lifting. Below is some of the boilerplate I use for generating the proper headers, etc. Whenever the user uploads a CSV file, the records will get saved in the table and then displayed on the index page. Export MySQL to CSV With PHP. Exporting data from MySQL database to a CSV file is similarly very easy. To demonstrate this, I will use the index.php that I created earlier. Add the following code to the file.

How To Export Posts To CSV In WordPress, On the click of this button, we will write a code for generating a CSV. Open your functions.php file and place the below code in it. 1. Create and Download CSV file. Create a new download.php file. Unserialize the $_POST['export_data'] value using unserialize() function which returns an array and using this to insert data in open file using fputcsv() method. Within fputcsv() passing two parameters – File variable and; An array value.

  • Why are you using the Location header?
  • Grégory, could you open the Web Developer Tools (F12) when the download.php is open, refresh the page, on the tools navigate to "Network", filter on the "Doc" node and then post a screenshot of the response header and response itself?
  • @SaschaM78 I just added the screenshot. Ok for the next edit, I will keep the former code.
  • As you can see the "download.php" can not be found, a 404 means "Page not found". Make sure that the file really is in "plugins/wp-admin".
  • @SaschaM78 Great it works. I will answer my question with your message.
  • I have done your corrections but it still doesn't work. I edited the code in the question so you can have a look.
  • @GrégoryHuyghe just saw that you changed the code. Just a short advice for the future, if you update your question, add the changed part below your original question. That helps preserve the original question and if people have similar problems they can use your question to troubleshoot their situation. I added a comment to your question above.
  • I included the solution in my answer. Would appreciate if you would mark it as an answer :-). Thanks and good you found the solution!
  • @Greogry this is not the correct way to access the path in WordPress, you have to create the action and then trigger those action using add_action.this way has a security risk
  • @ProblemSolver Ok, what is the correct action for a download? Init?
  • @GrégoryHuyghe sorry, I don't exactly get what you mean here. "?action=download" sounds like the right kind of passing the download action as parameter in the URL, if that's what you mean.