Link to home
Start Free TrialLog in
Avatar of deharvy
deharvy

asked on

Export to Excel File

This piece of simple code doesn't seem to work any longer since installing a new server.

if( $_GET['action'] == 'excel') {
      header("Content-type: application/octet-stream");
      header("Content-Disposition: attachment; filename=spreadsheet.xls");
}

I'm trying to simply export data to an excel spreadsheet. This should give the option to download the file.

Thanks!
Avatar of hielo
hielo
Flag of Wallis and Futuna image

Try:
header("Content-type: application/vnd.ms-excel");

Avatar of deharvy
deharvy

ASKER

I tried the suggested. it did not work. Any other suggestions?
ASKER CERTIFIED SOLUTION
Avatar of hielo
hielo
Flag of Wallis and Futuna image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Here is part of my code that I use on a site for clients to download in csv or xls format.
The csv or xls data is formatted in the $contents variable and the $filename variable is just 'whatever.csv' or 'whatever.xls'.
These headers work well with both csv and xls.

// Create some http headers
header("Pragma: public"); // required
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false); // required for certain browsers
header("Content-Type: application/octet-stream"); // may also try 'application/force-download'
header("Content-Disposition: attachment; filename=\"".$filename."\";" );
header("Content-Length: ".strlen($contents));
echo stripslashes($contents);
Avatar of deharvy

ASKER

Thanks for all your help. Instead of using if( strtolower($_REQUEST['action']) == 'excel') to indicate equals excel, how do I say either startsWith or includes excel? Maybe that will resolve the issue for me.
if( FALSE !== stristr( strtolower($_REQUEST['action']),'excel') )
{
header("Content-type: application/octet-stream");
      header("Content-Disposition: attachment; filename=spreadsheet.xls");

}
Avatar of deharvy

ASKER

Ok. Thanks! It's still not working and I'm not sure why. My link is: test.php?action=excel&name=sample

I'm sure the suggested codes above are accurate; I'm probably just doing something strange.
Avatar of deharvy

ASKER

I was able to test to validate that the action 'excel' is being met. I did so by doing:

if( $_GET['action'] == 'excel') {
 echo "test";
}

So, what else could be wrong? I tried on a different server and it works. Is there something with my PHP version?

Here is the version: PHP Version 4.4.7
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Try:
Content-Type

instead of:
Content-type
Avatar of deharvy

ASKER

Heilo: I'm using "Content-Type". It doesn't resolve the issue.

Ray: I used your debugging code and I think it helps. I get the following:

Notice: Undefined index: action in /home/www/test.php on line 172

------------------------

Starting at line 172.......

if( $_GET['action'] == 'excel') {
      header("Pragma: public"); // required
      header("Expires: 0");
      header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
      header("Cache-Control: private",false); // required for certain browsers
      header("Content-Type: application/force-download");
      header("Content-Disposition: attachment; filename=\"".$filename."\";" );
      header("Content-Length: ".strlen($contents));
      echo stripslashes($contents);
      }
>>Undefined index: action
that means that the key 'action' in $_GET['action'] does not exist. Make sure you are supplying the correct key on the url. Example if you are sendig the user to:
site.com/download.php? action=excel
then the problem is that the "key" is not "action" but rather " action". Notice the leading space. Also makesure you are not supplying ACTION or Action. Provide the correct case as well.
hielo is correct.

You just simply need to check if the $_GET['action'] is set.

if ((isset($_GET['action'])) && ($_GET['action'] == 'excel'))
{
      // put your header code here
}
Avatar of deharvy

ASKER

Heilo: Thanks for the explanation. My link is: http://website/test.php?action=excel&name=sample

Ray: Thanks for the code. I used it and it removed the startup index error. However, it doesn't export to excel. I'm going to create a simple page on my website and see if that works. I'll get back to you.
You should post your entire code so we can see where the problem is.
For us, it would be very simple to figure out if we could see it.
See if this helps you determine the values seen by the script:
if( isset($_REQUEST['action']) && ($_REQUEST['action'] == 'excel') ) {
      //header("Content-Type: application/octet-stream");
      header("Content-Type: application/vnd.ms-excel");

      header("Content-Disposition: attachment; filename=spreadsheet.xls");

      }
       else
       {
             echo "isset: " . isset($_REQUEST['action']);
            echo "action: " . $_REQUEST['action'];
}

Just so we are clear, this line:
header("Content-Disposition: attachment; filename=spreadsheet.xls");

DOES NOT send the spreadsheet.xsl file to the browser. It merely tells the browser, it is about to receive a file named spreadsheet.xls

To actually send the contents of the file, you would need to open the file (look up fopen), read its  contents, add a Content-Lenght header, and lastly, echo/print the contents of the file. If you do not echo/print the contents of the file, the browser will not receive anything.
Avatar of deharvy

ASKER

At the top of the page, I see this:

isset: action:

I guess it's not finding the first condition.
>>I guess it's not finding the first condition.
Correct.

If you actually provided a querystring, like this:
http://website/test.php?action=hi&name=sample

Then 'action' should report something in the else. It does not have to have excel as its value.
Avatar of deharvy

ASKER

Oddly enough, I used this code:
if( isset($_GET['action']) && ($_GET['action'] !== 'excel') ) {

When I did this, I got this output:
isset: 1action: excel

This indicates to me that the proper values are being met. That's frustrating.

(I know I've taken up alot of your time. Let me know when it's time to move on)
Based on your previous post, we are getting somewhere. Let's cast the $_GET to a string and see if it helps:
if( isset($_REQUEST['action']) && ( strval($_REQUEST['action']) === 'excel') ) {
        echo "ready to send file!"
      }
       else
       {
             echo "isset: " . isset($_REQUEST['action']);
            echo "action: " . $_REQUEST['action'];
}

Open in new window

Avatar of deharvy

ASKER

It definitely outputs "ready to send file!"

However, I added:

header("Content-Type: application/vnd.ms-excel");
header("Content-Disposition: attachment; filename=spreadsheet.xls");

Unfortunately, it still doesn't export to a file. ;(
>>It definitely outputs "ready to send file!"
OK. This is great news.

Simply adding:
header("Content-Type: application/vnd.ms-excel");
header("Content-Disposition: attachment; filename=spreadsheet.xls");

will not cause the server to send the file to the client. You need to actually "send" something. I explained this issue above (http:#20780383). On the code below I am "sending" the contnent by simply echoing the file contents. Try the code below.
if( isset($_REQUEST['action']) && ( strval($_REQUEST['action']) === 'excel') )
{
	header("Content-Type: application/vnd.ms-excel");
	header("Content-Disposition: attachment; filename=spreadsheet.xls");
	echo('<table><tr><th>State</th><th>Name</th></tr><tr><td>CA</td><td>California</td></tr><tr><td>NY</td><td>New York</td></tr></table>');
}
else
{
	echo "isset: " . isset($_REQUEST['action']);
	echo "action: " . $_REQUEST['action'];
}

Open in new window

Avatar of deharvy

ASKER

The page echos:

State      Name
CA      California
NY      New York

But not in a file, just a web page. :(
Did you copy and paste from my post above. I just tested it and it works perfectly for me.
Avatar of deharvy

ASKER

Heilo: I really don't think the issue has to do with the code. I think there is something with the PHP version.

On a different server that uses a different version of PHP, the initial code works (as does your code above).

I'm trying to migrate to a new host that uses PHP 4.4.7. There has to be something there. What version of PHP are you testing with?
I have PHP 5.2.1
BTW, look at the example by "lasitha dot alawatta at gmail dot com" on "29-Jul-2007 01:15" at http://us.php.net/header. Also, read the one right above it. Not sure if you are using IE7.
Avatar of deharvy

ASKER

Heilo, first off, you have been great.

Just creating a simple page, it works:

<?php
      header("Content-Type: application/vnd.ms-excel");
      header("Content-Disposition: attachment; filename=spreadsheet.xls");
      echo('<table><tr><th>State</th><th>Name</th></tr><tr><td>CA</td><td>California</td></tr><tr><td>NY</td><td>New York</td></tr></table>');
?>

There is definitely something in my full code that's messing things up.
Avatar of deharvy

ASKER

I think I made some progress:

Warning: Cannot modify header information - headers already sent by....

That's when I put the code in debugging mode. Any ideas?
Avatar of deharvy

ASKER

Warning: Cannot modify header information - headers already sent by (output started at /homepages/website/test.php:1) in /homepages/website/test.php on line 173
Warning: Cannot modify header information - headers already sent by (output started at /homepages/website/test.php:1) in /homepages/website/test.php on line 174

The web says it's an infamous "whitespace" issue.

My first few lines are at the bottom

-------------------------------

<?php
///*
error_reporting(E_ALL);
ini_set('error_reporting', E_ALL);
ini_set('display_startup_errors','1');
ini_set('display_errors','1');
//*/
Avatar of deharvy

ASKER

Thanks for all your help!
Avatar of deharvy

ASKER

All along, it appears the problem was the whitespace on the very first line of my code. I simply placed the file on a Unix server, used 'vi' to edit it and removed the junk.

I learned many troubleshooting routines in this post that will be valuable well into the future. Error checking, Manipulating header output, echoing to validate values... all important stuff.

Thanks to all (especially heilo) for your help!