Exporting data to csv in WordPress with PHP

In WordPress plugin development, sometimes you may need to export data to a csv file. Here we share how to implement it with PHP code.

How to export a csv file with PHP code

header() is used to send a raw HTTP header. To export a generated csv file, use below headers to tell the browser display a save dialog.

header( 'Content-Type: text/csv' ); // Supply the mime type
header( 'Content-Disposition: attachment; filename="downloaded.pdf"' ); // Supply a file name to save

Note:

There is not official RFC document for CSV files. text/csv is not a standard mime type, but it is more clear and works fine. application/octet-stream can also be used for csv files. However it is a very generous and it does not hint which application should be used to open the file.

Use two more headers to tell the content should not be cached by browser or any caches between the server and the browser.

header( "Cache-Control: no-cache, must-revalidate" );
header( "Expires: Sat, 26 Jul 1997 05:00:00 GMT" ); // Date in the past

Then echo the generated csv content directly:

echo $csv;
exit;

Note:

Any actual content must be output after header(). One common error is outputting content before header() by include or require a file. See more about header().

Example: Export data to csv in WordPress

Below is the full example which exports a table-like data to a CSV file for the user to download.

Add an export button in an page, below code adds a button for an admin page:

<a href="admin.php?page=export_example&export=table&noheader=1">Export</a>

Don’t forget to replace the page=export_example to your own page on which you want to do data exporting. The last two parameters in the URL:

  • export=table, it is used to tell the PHP code in the page to do the export. In this example, the code displayed below will check it and then do the CSV exporting. You can replace it with your own as long as you replace the parameter in the code as well.

  • nohead=1 Note without noheader parameter, the CSV content will directly be printed and there will be no Save dialog box popping up in the browser.

In the same page, we process the export in the start of the file as below:

<?php
$table_head = array( 'column1', 'column2', 'column3' );
$table_body = array(
    array( 'a', 'b', 'c' ),
    array( 'd', 'e', 'f' )
);

// Process export
if( isset( $_GET['export'] ) ) {
    $csv = implode( $table_head, ',' );
    $csv .= "n"; // important! Make sure to use use double quotation marks.
    foreach( $table_body as $row ) {
        $csv .= implode( $row, ',' );
        $csv .= "n";
    }

    $filename = 'table.csv';
    header( 'Content-Type: text/csv' ); // tells browser to download
    header( 'Content-Disposition: attachment; filename="' . $filename .'"' );
    header( 'Pragma: no-cache' ); // no cache
    header( "Expires: Sat, 26 Jul 1997 05:00:00 GMT" ); // expire date

    echo $csv;
    exit;
}
?>
<a href="admin.php?page=export_example&export=table&noheader=1">Export</a>

For simplicity, we export a simple two-dimensional data with columns ['column1', 'column2', 'column3'], and 2 rows ['a', 'b', 'c'], ['d', 'e', 'f']. In the practical situation, you may need to export data from a database or a table HTML element which contains the data.

This example works well on Firefox, IE, Chrome.

Export data with Unicode characters to utf-8 bom csv

If your data contains Unicode characters, you may want to export a utf-8 bom csv that Excel will read properly. To achieve that, just output the BOM mark before data:

echo "xEFxBBxBF"; // UTF-8 BOM
echo $csv;
exit;

4 Replies to “Exporting data to csv in WordPress with PHP”

    1. Hi wearewyze,

      I had tested the solution and yes, it works with the WP admin area but you have to place your page name on this part of the url

      ?page=page_name_were_you_are&export=table=noheader=1

      For example, i used this on a plugin call “stock manager for woocommerce”:

      admin?page=stock-manager-log&export=table&noheader=1

      hope this could help you.

      Thank you gloomy corner for the post.

Leave a Reply