My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
QuickUsageGuide  
Quick and dirty guide to using php-excel.
Phase-Implementation, Featured
Updated Feb 4, 2010 by oliver.s...@gmail.com

Introduction

php-excel is a very, very simple class to generate excel 2003 files from PHP5 using the excel XML-notation. The main advantage is its easy handling and quick implementation.

Prerequisites

php-excel expects a two-dimensional array and dumps it into columns and rows. Please first download the file from the branches directory.

Inclusion

Step 01: Just put the class-excel-xml.inc.php in your project directory and include it using (of course you may choose to put it wherever you like):

require (dirname (__FILE__) . "/class-excel-xml.inc.php");

Step 02: For testing, create a two dimensional array:

$myarray =  array (
       1 => array ("Oliver", "Peter", "Paul"),
            array ("Marlene", "Mica", "Lina")
    );

Step 03: Instanciate class and dump the array into the document.

$xls = new Excel_XML;
$xls->addArray ( $myarray );
$xls->generateXML ( "testfile" );

The document (with filename "testfile") will be delivered to your browser for downloading. All values of the array will be defined as "string" - I may at support for more types later.

Comment by kusalsm...@gmail.com, Oct 20, 2007

Thnx a lot, this code really helped me :-) saved lot of time.

Kusal

Comment by jpee...@gmail.com, Oct 30, 2007

Big thanks dude ! Worked like a charm first time I ran it, just the way I like it. You don't have a class like this for Word lying around, by any chance ?

Oh, and just an FYI: on my office 2003, everything works perfectly. On office 2007, the user is prompted with a security alert, saying the contents of the .xls is not really Excel data (duh, it's XML). It can still import it, the user just has to click 'Yes, I trust it!'.

Comment by eivind.r...@gmail.com, Nov 8, 2007

// Here is a little modification to support numbers, by Eivind, Norway

// foreach key -> write value into cells foreach ($array as $k => $v):

if(is_numeric(utf8_encode($v)))

$cells .= "<Cell><Data ss:Type=\"Number\">" . utf8_encode($v) . "</Data></Cell>\n";
else
$cells .= "<Cell><Data ss:Type=\"String\">" . utf8_encode($v) . "</Data></Cell>\n";

endforeach;

Comment by xmar...@gmail.com, Nov 13, 2007

Building on Eivind's work, we had an additional requirement. Numbers that are zero-padded need to be preserved as strings (e.g., 000123). Here is the code change to accomplish this:

    private function addRow ($array)
    {

        // initialize all cells for this row
        $cells = "";

        // foreach key -> write value into cells
        foreach ($array as $k => $v):
			if (is_numeric($v)) {
				//if is numeric and starts with zero, and is not zero and is not zero-decimal:

				if (substr($v, 0, 1) == "0" && $v != 0 && substr($v, 0, 2) !== "0.") {
					$type = "String";
				} else {
					$type = "Number";
				}
			} else {
				$type = "String";
			}

			$cells .= "<Cell><Data ss:Type=\"$type\">" . utf8_encode($v) . "</Data></Cell>\n";

        endforeach;

        // transform $cells content into one row
        $this->lines[] = "<Row>\n" . $cells . "</Row>\n";

    }
Comment by BretSimp...@gmail.com, Jan 28, 2008

I get the following error from your class-excel-xml.inc.php file: Parse error: parse error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /home/httpd/Application08/class-excel-xml.inc.php on line 63

Comment by ammonbr...@gmail.com, Jan 30, 2008

Bret, this is a PHP4 vs PHP5 issue. You can either upgrade your PHP or downgrade the code. Upgrading PHP is better if possible. PHP4 does not recognize the public/private distinction in classes, so remove it to downgrade. Change the public or private in front of each variable to "var" and then remove it from in front of each function.

Comment by tdero...@gmail.com, Feb 23, 2008

I needed tot save the XLS instead of pointing it to the browser:

    /**
     * generateAndSaveXML
     * 
     * Generate the XML and save to file
     *
     * @param unknown_type $filename
     */
    function generateAndSaveXML ($path, $filename){
    	
    	$content = stripslashes ($this->header);
    	$content .= "\n<Worksheet ss:Name=\"" . $this->worksheet_title . "\">\n<Table>\n";
    	$content .= "<Column ss:Index=\"1\" ss:AutoFitWidth=\"0\" ss:Width=\"110\"/>\n";
    	$content .= implode ("\n", $this->lines);
    	$content .= "</Table>\n</Worksheet>\n";
        $content .= $this->footer;
    			
		if (!$handle = @fopen($path . $filename, 'w+')){
			return false;
		}
		if (@fwrite($handle, $content) === false){
			return false;
		}
		@fclose($handle);
		return true;
    	
    }

// Call using: 
$xls->generateAndSaveXML($_SERVER['DOCUMENT_ROOT'] . '/excel/', 'output.xls');
Comment by jfauch...@gmail.com, Mar 28, 2008

addRow() method is set to private. Should be public. Works great once set to public. Thanks!

Jack

Comment by mohfa...@gmail.com, Jul 13, 2008

Hi there, Firstly I would like to thank you bcoz of the code and secondly I would like to ask you guys that how can I get data from an EXCEL file, modify and update the EXCEL file again!

any suggestions plz email me at mohfazel@gmail.com or I will check here straight away.

Comment by gugli100, Aug 5, 2008

I'm sad that doesn't work with OpenOffice? :(

Comment by tony.byo...@gmail.com, Aug 23, 2008

This library worked for me and saved time. Just an hour to modify a php page and route output into Excel.

Would it be feasible to modify the class so it provides some basic formatting controls such as column width and bold fonts?

Comment by inspire...@gmail.com, Sep 12, 2008

Thinks

Comment by lescouti...@gmail.com, Sep 30, 2008

thanks! worked perfectly

<?php

require (dirname (FILE) . "/class-excel-xml.inc.php");
$connection = mysql_connect("localhost", "user", "password"); mysql_select_db("database", $connection);
$query = "select name, email, college
from user u u join college c on u.id_college = c.id";
$result = mysql_query($query) or die($query . '<br>' . mysql_error()); $myarray = array(); while($row = mysql_fetch_array($result)) {
$myarray = array($row['name'], $row['email'], row['college']);
}
$xls = new Excel_XML; $xls->addArray ( $myarray ); $xls->generateXML ( "testfile" );

?>

lescoutinhovr@gmail.com

Comment by ni...@electricpencil.co.za, Oct 6, 2008

this certainly does make it easy! only one issue i am having... ie7 simply renders the xml in the browser... no download/save dialogue. works a treat in firefox though.

any ideas?

Comment by gmea...@gmail.com, Oct 28, 2008

1. Excel fails to read in cells that contain un-encoded XML entities: ampersand, apostrophe, double-quote, less-than and greater-than. So in addRow, all cells should be encoded:

$cells .= "<Cell><Data ss:Type=\"$type\">" . utf8_encode($this->xmlspecialchars($v)) . "</Data></Cell>\n";

with this function: public function xmlspecialchars($text) { return str_replace('&#039;', '&apos;', htmlspecialchars($text, ENT_QUOTES)); }

Comment by rr...@nurserysupplies.com, Nov 12, 2008

another extrapolation:

just pass in an SQL command:

// instantialte the class
   $xls = new Excel_XML;
   if($xls->AddRows_RS($query))$xls->generateXML ();

and process it (sorry for bloated code, you know PHP so do however you feel is best)

// add new var
var worksheet_labels=true;
function hideColumnLabels()
{
    $this->worksheet_labels=false;
}

function AddRows_RS($sql)
{
    include(dirname(__FILE__)."/configfile.php"); 
    $connection = mysql_connect($dbServer, $dbUsername, $dbPassword); 
    if($connection)
    {
        mysql_select_db($dbDatabase, $connection);
        $result = mysql_query($sql) or die($query . '<br>' . mysql_error()); 
        // get the header row, column field names from SQL
        if($result)
        {
            $type = "String";
            $cells = "";
            if($this->worksheet_labels) 
            {
                for($i=0;$i<mysql_numfields($result);$i++)$cells .= "<Cell><Data ss:Type=\"$type\">" . utf8_encode($this->xmlspecialchars(mysql_fieldname($result, $i))) . "</Data></Cell>\n";
                $this->lines[] = "<Row>\n" . $cells . "</Row>\n";
            }
            while($row = mysql_fetch_array($result))
            { 
                $cells = "";
                for($i=0;$i<mysql_numfields($result);$i++)
                {
                    //(retain strings like '00123')if is numeric and starts with zero, and is not zero and is not zero-decimal: 
                    if (is_numeric($row[$i])) 
                    {
                        if (substr($row[$i], 0, 1) == "0" && $row[$i] != 0 && substr($row[$i], 0, 2) !== "0.") $type = "String";
                        else $type = "Number";
                    } 
                    else $type = "String";
                    $cells .= "<Cell><Data ss:Type=\"$type\">" . utf8_encode($this->xmlspecialchars($row[$i])) . "</Data></Cell>\n";
                }
                $this->lines[] = "<Row>\n" . $cells . "</Row>\n";
            }
            mysql_free_result($result);
        }
        else // no results else
        {
          return false;   
        }
        mysql_close($connection);
    }
    else // connection failed else
    {
      return false;
    }
    return true;
}
Comment by ewmu...@gmail.com, Nov 17, 2008

Is there any way to make this work with OpenOffice??? If so, how? Thanks!!

Comment by jej1...@gmail.com, Nov 25, 2008

I used this great Wiki to get exactly what I needed - output to an Excel Spreadsheet including the column headers: <?php // include the php-excel class require (dirname (FILE) . "/class-excel-xml.inc.php");

$connection = mysql_connect("server", "id", "password"); mysql_select_db("database", $connection);

$query = "SELECT FROM incidents";

$result = mysql_query($query) or die($query . '<br>' . mysql_error());

$myheaderarray = array(); $myheaderarray = array('STAMP','incident_id','fac_id','room_descr','oth_descr','person_type','medrec_num','acct_num','person_name', 'person_lname','person_street','person_city','person_state','person_zip','person_phone','dob','inc_date', 'inc_time','fall_type','assisted','observe','fall_type2','assisted2','observe2','treat_var','med_var','pt_outcome', 'pt_outcome_oth', 'ni_type','pt_rights','near_miss','equip','environ','desc_oth','inc_descr','injury','inj_descr', 'rel_factor_fall', 'rel_factor_fall2','rel_factor_fall3','rel_factor_fall4','rel_factor_meds','rel_factor_oth', 'severity','not_type','note_oth','not_time','not_type2','note2_oth','not_time2','not_type3','note3_oth','not_time3', 'not_type4','note4_oth','not_time4','witness1_type','witness1_name','witness1_street','witness1_city','witness1_st', 'witness1_zip','witness1_phone','witness2_type','witness2_name','witness2_street','witness2_city','witness2_st', 'witness2_zip','witness2_phone','reporting_name','reporting_id','reporting_date','assess_ortho','rescore_morse', 'det_contrib','id_rec_medment','req_pharm_review','rev_curr_int','id_add_int','addr_bwlblddr','assure_safety_equip', 'id_env_issues','id_learn_pref','comm_team','comm_fam','notify_attending','comm_name','actions_descr','followup_descr', 'rm_severity','notified_ceo','not_ceo_datetime','notified_ho','not_ho_datetime','notified_plant','not_plant_datetime', 'notified_food','not_food_datetime','notified_attending','not_sattending_datetime','notified_ins','not_ins_datetime', 'notified_pharm','not_pharm_datetime','notified_dno','not_dno_datetime','notified_dto','not_dto_datetime','notified_oth', 'not_oth_datetime','not_oth_descr','root_cause_an','rca_date','rm_name','rm_date','Done');

$myarray = array(); while($row = mysql_fetch_array($result)) {

$myarray = array($row['STAMP'], $row['incident_id'], $row['fac_id'], $row['room_descr'], $row['oth_descr'], $row['person_type'], $row['medrec_num'], $row['acct_num'], $row['person_name'], $row['person_lname'], $row['person_street'], $row['person_city'], $row['person_state'], $row['person_zip'], $row['person_phone'], $row['dob'], $row['inc_date'], $row['inc_time'], $row['fall_type'], $row['assisted'], $row['observe'], $row['fall_type2'], $row['assisted2'], $row['observe2'], $row['treat_var'], $row['med_var'], $row['pt_outcome'], $row['pt_outcome_oth'], $row['ni_type'], $row['pt_rights'], $row['near_miss'], $row['equip'], $row['environ'], $row['desc_oth'], $row['inc_descr'], $row['injury'], $row['inj_descr'], $row['rel_factor_fall'], $row['rel_factor_fall2'], $row['rel_factor_fall3'], $row['rel_factor_fall4'], $row['rel_factor_meds'], $row['rel_factor_oth'], $row['severity'], $row['not_type'], $row['note_oth'], $row['not_time'], $row['not_type2'], $row['note2_oth'], $row['not_time2'], $row['not_type3'], $row['note3_oth'], $row['not_time3'], $row['not_type4'], $row['note4_oth'], $row['not_time4'], $row['witness1_type'], $row['witness1_name'], $row['witness1_street'], $row['witness1_city'], $row['witness1_st'], $row['witness1_zip'], $row['witness1_phone'], $row['witness2_type'], $row['witness2_name'], $row['witness2_street'], $row['witness2_city'], $row['witness2_st'], $row['witness2_zip'], $row['witness2_phone'], $row['reporting_name'], $row['reporting_id'], $row['reporting_date'], $row['assess_ortho'], $row['rescore_morse'], $row['det_contrib'], $row['id_rec_medment'], $row['req_pharm_review'], $row['rev_curr_int'], $row['id_add_int'], $row['addr_bwlblddr'], $row['assure_safety_equip'],$row['id_env_issues'], $row['id_learn_pref'], $row['comm_team'], $row['comm_fam'], $row['notify_attending'], $row['comm_name'], $row['actions_descr'], $row['followup_descr'], $row['rm_severity'], $row['notified_ceo'], $row['not_ceo_datetime'], $row['notified_ho'], $row['not_ho_datetime'], $row['notified_plant'], $row['not_plant_datetime'], $row['notified_food'], $row['not_food_datetime'],$row['notified_attending'],$row['not_sattending_datetime'], $row['notified_ins'], $row['not_ins_datetime'], $row['notified_pharm'], $row['not_pharm_datetime'], $row['notified_dno'], $row['not_dno_datetime'], $row['notified_dto'], $row['not_dto_datetime'], $row['notified_oth'], $row['not_oth_datetime'], $row['not_oth_descr'], $row['root_cause_an'], $row['rca_date'], $row['rm_name'], $row['rm_date'], $row['Done']);
}

// generate excel file $xls = new Excel_XML; $xls->addArray ( $myheaderarray ); $xls->addArray ( $myarray ); $xls->generateXML ( "incidents" );

?>

Comment by jimn...@gmail.com, Dec 19, 2008

ewmusso

I got it to work with open office.

Go to the generateXML function. Change the file extension at the second header() call from xls to xml.

Done.

Comment by v.gowris...@gmail.com, Dec 24, 2008

can some one suggest how I could add images into the file?

Comment by z1n...@gmail.com, Jan 18, 2009

Thanks a Lot - great simple thing

For Russian users (when content data in CP1251):

In class-excel-xml.inc.php replace all 'UTF-8' to 'WINDOWS-1251' and replace 'utf8_encode($v)' to just '$v' (private function addRow)

Comment by janssen1...@gmail.com, Feb 8, 2009

Here is a reduced version for php4:

<?php class Excel_XML { var $header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?\> <Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"

xmlns:x=\"urn:schemas-microsoft-com:office:excel\" xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\" xmlns:html=\"http://www.w3.org/TR/REC-html40\">";
var $footer = "</Workbook>"; var $lines = array (); var $worksheet_title = "Table1"; function addRow ($array)
{
$cells = ""; foreach ($array as $k => $v):
$cells .= "<Cell><Data ss:Type=\"String\">" . utf8_encode($v) . "</Data></Cell>\n";
endforeach; $this->lines = "<Row>\n" . $cells . "</Row>\n";
}
function addArray ($array)
{
foreach ($array as $k => $v):
$this->addRow ($v);
endforeach;
}
function setWorksheetTitle ($title)
{
$title = preg_replace ("/[\\\|:|\/|\?|\|\[|\]]/", "", $title); $title = substr ($title, 0, 31); $this->worksheet_title = $title;
}
function generateXML ($filename)
{
header("Content-Type: application/vnd.ms-excel; charset=UTF-8"); header("Content-Disposition: inline; filename=\"" . $filename . ".xls\""); echo stripslashes ($this->header); echo "\n<Worksheet ss:Name=\"" . $this->worksheet_title . "\">\n<Table>\n"; echo "<Column ss:Index=\"1\" ss:AutoFitWidth?=\"0\" ss:Width=\"110\"/>\n"; echo implode ("\n", $this->lines); echo "</Table>\n</Worksheet>\n"; echo $this->footer;
}
} ?>

Comment by chad.big...@gmail.com, Feb 9, 2009

A quick comment on the PHP4 code above...

The "AutoFitWidth?" line should not have the question mark. At least it did not work for me with it in.

Just FYI. Thanks janssen1990!

Comment by desaise...@gmail.com, Feb 18, 2009

hi one small doubt, I need to generate multiple sheets in same excel file and need to write data to those sheets can u please help me out..... Thanks in Advance

Seenu

Comment by desaise...@gmail.com, Feb 18, 2009

hi one small doubt, When i try to upload the spread sheet that i got from the above code i get "the file is not readable error" can u please help me out..... Thanks in Advance

Seenu

Comment by sita...@gmail.com, Mar 9, 2009

It's nice and work fine! Thanks

Comment by esom...@gmail.com, Mar 16, 2009

nice work guys! would be nice to have column header formating options

Comment by kingzjes...@gmail.com, May 11, 2009

That worked really well! Thanks!

I did however change the addRow to a public function since I really didn't want to feed the entirety of my db into a variable, and then feed that to a file; it seemed redundant. What is the reason for having it be private anyway?

Comment by z1n...@gmail.com, May 28, 2009

Where is a problem with MS IE8 generateXML is not work with it (in IE7 and FF3 work well) The error is looks like:

"the file is not readable error"

Comment by z1n...@gmail.com, May 28, 2009

found solution with "the file is not readable error": http://ru2.php.net/manual/ru/function.header.php#88038

Need add some headers in function generateXML:

header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Transfer-Encoding: binary");

(exactly don't know wich one help me)

Comment by zfpri...@gmail.com, Jul 22, 2009

Nice tutorial.....It's very helpful.

Zamshed Farhan http://www.zamshed.info

Comment by deepak...@gmail.com, Aug 9, 2009

how to put image with excel spredsheet ?

Comment by MichaelD...@gmail.com, Aug 19, 2009

this is a great tool. is there a way to make a hyperlink cell?

Comment by project member oliver.s...@gmail.com, Sep 10, 2009

Thanks a lot for all these comments. I haven't exactly reviewed all of them, but a few issues have been fixed with the new version 1.1. Please check the download section of the project. Here are a few answers to some comments:

@xmarkvh (from 2007): I will see if I can improve the issue with the automatic type conversion (strings <> numbers). Sometimes, you do not want to convert values to numbers (article numbers starting with zero). I will see, if I can improve this in later version.

@z1nkum (Jan 2009): Version 1.1 now provides the remote setting of the charset in the constructor:

$xls = new Excel_XML('WINDOWS-1251');

should do the trick ;)

@z1nkum (May 2009): I haven't tested this yet in IE8. I may improve the header-directive settings in the next version. Thanks for the input!

@jimnau9 (Dec 2008): Thanks for the input. I will implement an MS Excel/OpenOffice? switch in the next versions.

Comment by project member oliver.s...@gmail.com, Sep 10, 2009

@gmeader (Oct 2008): Converting chars while writing into the cells is a question of performance. This is a great piece of code you put there! I will see if I can adapt this. I have to do some tests for this.

Comment by rajan.ma...@gmail.com, Mar 19, 2010

How to make hyper link?

Comment by shaman...@gmail.com, May 17, 2010

this class ain't generate binary XLS file (try to open it with any text editor and see the XLS tags it has) so unfortunately it won't be processed by Open Office correctly...or we need another proper format for it...

Comment by munawwar...@gmail.com, Apr 9, 2011

If you manually rename the .xls file to .xml or .ods (OpenDocument? Spreadsheet), then OpenOffice? can open the file correctly. Tested on OpenOffice? 3.2.1. What I believe is OpenOffice? can open any file that's of Microsoft's OOXML format, but it screws up with .xls.

Comment by schwarze...@gmail.com, Sep 12, 2011

Modify the header with xls to xlsx, this will specify that the original format is xml


Sign in to add a comment
Powered by Google Project Hosting