Reputation: 987
Context:
I plan to use the PHPSpreadsheet to extend an event planner plugin on wordpress to create an export in wordpress. I'm using the PHPSpreadsheet package, starting with the basic example given on the PHP Spreadsheet Doc site.
It's a self processing page. They click an export button, it triggers the page again with a query string that determines what data to put in the spreadsheet.
The Problem:
The script is currently not doing anything besides following the simple PHPSpreadsheet example. The download triggers fine, but when I go to open the file I get the following errors.
We found a problem with some content in 'storage_report.xlsx'. Do you want us to try to recover as much as we can?
Click yes.
Microsoft Excel was attempting to open and repair the file. To start this process again, choose Open and Repair from the Open file dialog.
Click Ok.
It then opens a blank document. Here is code.
<?php
require dirname( __FILE__ ) . '/../../vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
if(!defined('ABSPATH')) {die('You are not allowed to call this page directly.');}
add_action( 'admin_menu', 'registryExport::menu' );
add_action( 'init', 'registryExport::export' );
class registryExport
{
/*
TODO:
- Display into submenu in WP Admin
- Find and retrieve epl-data
*/
/*
Add button to plugin dropdown
Clicking Export sidebar submenu item triggers admin_page()
*/
public static function menu()
{
add_submenu_page('edit.php?post_type=epl_event', __('Export', 'epl_event_manager'), __('Export', 'epl_event_manager'), 'export', 'registryExport', 'registryExport::admin_page');
}
/*
Display the page in WP Admin for selecting export options
When button is clicked, export() is triggered
*/
public static function admin_page()
{
?>
<h1>
Export Registrations
</h1>
<hr>
<p>
<a class="button button-primary button-large" href="?post_type=epl_event&page=registryExport&type=all">
Export All
</a>
</p>
<?
}
/*
Checks URI for validity and export type
Triggers data retrieval and download of export file
*/
public static function export()
{
if ( self::isValidUri() )
{
$type = $_GET[ 'type' ]; // Type of export
// Use switch to allow for more types to be added later on
switch ( $type )
{
case( 'all' ):
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 'Hello World !');
$writer = new Xlsx($spreadsheet);
try
{
$writer->save( "php://output" );
}
catch ( Exception $e )
{
self::pre( $e ); // just a print_r( $var ) wrapped in <pre>
die( "FAILED TO SAVE SPREADSHEET" );
}
// TODO: output headers so that the file is downloaded rather than displayed
header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); //for Excel2007
header('Content-Disposition: attachment; filename="storage_report.xlsx"');
die( "Export Button Triggered" );
break;
default:
die( 'Invalid Type selected' );
break;
}
}
}
/**
* Check if GET query values are set and valid
* @return boolean
*/
public static function isValidUri()
{
return ( isset( $_GET[ 'page'] ) && $_GET[ 'page' ] == 'registryExport' && isset( $_GET[ 'type' ] ) )
? true
: false;
}
/*
Nicely output pre-formated text
*/
public static function pre( $var )
{
if ( $var )
{
echo "<pre>";
print_r( $var );
echo "</pre>";
}
}
}
Solutions I've Tried:
$writer->save()
after the header change.php://output
Upvotes: 2
Views: 3991
Reputation: 26784
Just remove any output on your page, those headers will stumble upon it on execution.
die( "Export Button Triggered" );
die( 'Invalid Type selected' );
Upvotes: 1