Create CSV Exports of WordPress Data

If your plugin is storing any kind of data for the user, at some point they may want a feature to export that data into a format that they can work with.

Usually, this means a standard format that works well with spreadsheets or other tools.

CSV is a great format for exporting.

Today I’m going to walk through how you can quickly and efficiently export any data in WordPress into a CSV file.

Provide users with a way to handle their data however they need to

Since your plugin will be installed on a user’s site, all of the data belongs to that user. Be a good steward of data and allow them to export all of it.

Let’s walk through a proof-of-concept plugin I set up to show you how in three steps:

Step 1: Set up a button to trigger the CSV creation

The first step in this process is to create a button for the user to click that begins the generation of the CSV.

Note: This plugin is also available on Github if you’d rather reference the code there.

Here, the plugin sets up a new Menu Page and configures it to show in the sidebar as “CSV Export”

add_action( 'admin_menu', 'csv_export_init_menu');

function csv_export_init_menu() {
    add_menu_page(
        'CSV Export',
        'CSV Export',
        'manage_options',
        'csv_export',
        'csv_export_render'
    );
}

It then renders the content for the page using the csv_export_render hook.

function csv_export_render() {
    if ( ! current_user_can( 'manage_options' ) ) {
        return;
    }
    ?>
    <div class="wrap">
        <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
        <form action="" method="post">
            <?php wp_nonce_field( 'generate-csv' ); ?>
            <?php submit_button( 'Generate CSV' ); ?>
        </form>
    </div>
    <?php
}

Now that that’s been configured and set up, we have a custom settings page with a button for generating our CSV.

When the submit button is pressed, a hook called during init should:

  1. verify that a nonce was sent with the request (the user clicked the button)
  2. verify the nonce is valid
  3. create the CSV and save it to the uploads folder

Adding that functionality then looks like this:

add_action( 'admin_init', 'handle_csv_export' );

function handle_csv_export() {
		
		/**
		 * When the admin loads, check to see if the nonce was used
     * and is valid. If not, then just return and don't do anything.
     */
    if ( ! wp_verify_nonce( $_POST['_wpnonce'], 'generate-csv') ) {
        return;
    }
    
		// Generate CSV...
}

Step 2: Consider how the data should be structured

Whenever you generate a CSV, be sensitive to the columns that will be useful for the user.

Are you exporting a list of posts?

Give the user all the post meta they might need.

Are you exporting users?

You should include username and email, but don’t include their password.

Consider this carefully when deciding what to include and think through the context of your plugin and how your users might want their data.

Step 3: Generate the CSV

Now that you know how the CSV needs to be structured, you can use PHP’s fputcsv() function to manually build the file.

As an example, the proof-of-concept queries all the current site posts and uses them in the CSV.

First, you’ll need to open up the file using fopen() and you can provide a new file that doesn’t exist yet. Here is an example of creating a new file in a custom directory in the uploads folder.

$file = fopen( wp_get_upload_dir()['path'] . '/' . gmdate( 'now' ) . '.csv', 'w' );

This tells PHP to create a file and leave it open because we’ll be writing to it shortly.

Then, you’ll want to write out the first line—the column names.

fputcsv( $file, [
    'id',
    'post_author',
    'post_date',
    'post_content',
    'post_title',
    'post_status',
] );

Each time you use fputcsv(), you’ll need to pass in the file resource and an array of fields to add for the line.

For the rest of the CSV, the plugin queries the database for a list of posts, then loops through and outputs each post’s data on a new line in the file.

foreach ( $query->posts as $post) {
  // Loop through each post and output the fields for each line.    
  fputcsv( $file, [
    $post->ID,
    $post->post_author,
    $post->post_date,
    $post->post_content,
    $post->post_title,
    $post->post_status,
  ] );
}

Once we’re done writing the data to the file, make sure to use fclose() to signal to PHP we’re done writing to the file (and free up the memory used to keep it open).

fclose( $file );

Once the file has been generated, you can redirect users to the file URL to download it or do anything else you need to now that you have it.

In summary

Creating a CSV file isn’t too complex and your users will be glad to have an export feature.

It may be more complicated in a real-world solution, but I found it helpful to write out a proof-of-concept example to figure out the basics before expanding to a certain use case.

I hope this has been a helpful walkthrough. Hit reply and let me know if you have a CSV export feature in your plugin, or plan to add one now that you know how.