Dan
Dan

Reputation: 987

PHPSpreadsheet saving file in invalid format

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:

Upvotes: 2

Views: 3991

Answers (1)

Mihai
Mihai

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

Related Questions