You are probably executing your process_bulk_action
function in template where some html and headers are already sent. You have to use handle_bulk_actions-edit-post
hook to execute your code before any content is sent. This might look something like that:
function wpse_287406_register_export_option($bulk_actions) {
$bulk_actions['export_csv'] = __( 'Export to CSV');
return $bulk_actions;
}
add_filter( 'bulk_actions-edit-post', 'wpse_287406_register_export_option' );
function wpse_287406_export_csv( $redirect_to, $doaction, $post_ids ) {
if ( $doaction !== 'export_csv' ) {
return $redirect_to;
}
// Export CSV code
$file = realpath( dirname( __FILE__ ) . '/file.csv' );
header( 'Content-Description: File Transfer' );
header( 'Content-Type: application/octet-stream' );
header( 'Content-Disposition: attachment; filename=file.csv' );
header( 'Content-Transfer-Encoding: binary' );
header( 'Expires: 0' );
header( 'Cache-Control: must-revalidate' );
header( 'Pragma: public' );
header( 'Content-Length: ' . filesize($file) );
readfile($file);
exit;
}
add_action( 'handle_bulk_actions-edit-post', 'wpse_287406_export_csv', 10, 3 );