How to properly make Wordpress plugin return downloadable excel file
I am trying to do some reporting for my wordpress plugin. These reports must be downloadable as excel. Basically what I did was create a button and when that button was clicked I will query the database and do something different from the results.
Now I need to change the title to get the results back to the excel file. This is how I did it:
header('Content-Disposition: attachment; filename='.$filename.'.xls');
header('Content-type: application/force-download');
header('Content-Transfer-Encoding: binary');
header('Pragma: public');
print "\xEF\xBB\xBF"; // UTF-8 BOM
The problem is that it returns the following error:
Warning: Cannot modify header information - headers already sent by (output started at .....\wp-admin\menu-header.php:137)
I probably need ob_start () for this, but not that ob_start () should be placed before the first header (which is from the main Wordpress files). I prefer not to modify the kernel files if possible.
Or maybe Wordpress's own 'send_headers' hook? but I can't get it to work, it still generates the same error.
So what do I need to solve this problem? Is there any other way to recreate the excel file from the wordpress plugin?
Any help is appreciated!
source to share
You are sending the header too late as the header () has already been sent to menu-header.php. From the provided code, I can't see at what point you send the header, but a good place would be in the plugins_loaded action, after this action, the hook is called when all plugins are loaded and before any output is sent.
The download link might look like this:
<a href="<?php echo admin_url( '?download' ); ?>">download</a>
And, plugins_loaded action:
add_action( 'plugins_loaded', function() {
if ( isset( $_GET['download'] ) ) {
// here you can create .xls file
header('Content-Disposition: attachment; filename='.$filename.'.xls');
header('Content-type: application/force-download');
header('Content-Transfer-Encoding: binary');
header('Pragma: public');
die();
}
});
source to share