Jump to content

Creating Excel Spreadsheet With PHP - Script Not Working


Recommended Posts

I found this PHP class that creates an Excel spreadsheet.  I am trying to use the script as described in the tutorial but it's not working for me.  Could someone help me figure out why my variables show up as zeros in the outputted Excel spreadsheet, but if I were to echo these same variables they have other values?  I have tried contacting the author and the site that hosts the tutorial, but no go.  I'm hoping someone here can help me, please.

 

Here's the relevant parts of my script that I run via the command line....

require_once "excel.php";

$today = date("M_d_Y");
$filename = "Report_" . $today . ".xls";
$export_file = "xlsfile://Library/WebServer/Documents/report/archive/" . $filename;
$fp = fopen($export_file, "wb");
if (!is_resource($fp)) {
die("Cannot open $export_file");
}

$assoc = array(
array("Statistic" => "Page Loads", "Value" => $week_page_loads),
array("Statistic" => "Unique Visitors", "Value" => $week_unique_visits),
array("Statistic" => "Accounts Created", "Value" => $week_accts_created),
//these are the variables that show up as 0 in the spreadsheet, however i can echo all of them and get the correct value
);

fwrite($fp, serialize($assoc));

fclose($fp);

Here's the Excel class that I found....

<?php
/**
* MS-Excel stream handler
* This class read/writes a data stream directly
* from/to a Microsoft Excel spreadsheet
* opened with the xlsfile:// protocol
* This is used to export associative array data directly to MS-Excel
* @requires    PHP 4 >= 4.3.2
* @author      Ignatius Teo            <ignatius@act28.com>
* @copyright   (C)2004 act28.com       <http://act28.com>
* @version     0.3
* @date        20 Jan 2005
* $Id: excel.php,v 1.3 2005/01/20 09:58:58 Owner Exp $
*/
class xlsStream
{
    /* private */
    var $position = 0;          // stream pointer
    var $mode = "rb";           // default stream open mode
    var $xlsfilename = null;    // stream name
    var $fp = null;             // internal stream pointer to physical file
    var $buffer = null;         // internal write buffer
    var $endian = "unknown";	// little | unknown | big endian mode
var $bin = array(
	"big" => "v",
	"little" => "s",
	"unknown" => "s",
);

/**
 * detect server endian mode
 * thanks to Charles Turner for picking this one up
 * @access	private
 * @params	void
 * @returns	void
 * @see		http://www.phpdig.net/ref/rn45re877.html
 */
function _detect()
{
	// A hex number that may represent 'abyz'
	$abyz = 0x6162797A;

	// Convert $abyz to a binary string containing 32 bits
	// Do the conversion the way that the system architecture wants to
	switch (pack ('L', $abyz))
	{
	    // Compare the value to the same value converted in a Little-Endian fashion
	    case pack ('V', $abyz):
	        $this->endian = "little";
	        break;

	    // Compare the value to the same value converted in a Big-Endian fashion
	    case pack ('N', $abyz):
	        $this->endian = "big";
	        break;

	    default:
	        $this->endian = "unknown";
	        break;
	}
}

    /**
     * called by fopen() to the stream
     * @param   (string)    $path           file path
     * @param   (string)    $mode           stream open mode
     * @param   (int)       $options        stream options (STREAM_USE_PATH |
     *                                      STREAM_REPORT_ERRORS)
     * @param   (string)    $opened_path    stream opened path
     */
    function stream_open($path, $mode, $options, &$opened_path)
    {
        $url = parse_url($path);
        $this->xlsfilename = '/' . $url['host'] . $url['path'];
        $this->position = 0;
        $this->mode = $mode;

	$this->_detect();	// detect endian mode

        //@TODO: test for invalid mode and trigger error if required

        // open underlying resource
        $this->fp = @fopen($this->xlsfilename, $this->mode);
        if (is_resource($this->fp))
        {
            // empty the buffer
            $this->buffer = "";

            if (preg_match("/^w|x/", $this->mode))
            {
                // write an Excel stream header
                $str = pack(str_repeat($this->bin[$this->endian], 6), 0x809, 0x8, 0x0, 0x10, 0x0, 0x0);
                fwrite($this->fp, $str);
                $opened_path = $this->xlsfilename;
                $this->position = strlen($str);
            }
        }
        return is_resource($this->fp);
    }

    /**
     * read the underlying stream resource (automatically called by fread/fgets)
     * @todo    modify this to convert an excel stream to an array
     * @param   (int)       $byte_count     number of bytes to read (in 8192 byte blocks)
     */
    function stream_read($byte_count)
    {
        if (is_resource($this->fp) && !feof($this->fp))
        {
            $data .= fread($this->fp, $byte_count);
            $this->position = strlen($data);
        }
        return $data;
    }

    /**
     * called automatically by an fwrite() to the stream
     * @param   (string)    $data           serialized array data string
     *                                      representing a tabular worksheet
     */
    function stream_write($data)
    {
        // buffer the data
        $this->buffer .= $data;
        $bufsize = strlen($data);
        return $bufsize;
    }

    /**
     * pseudo write function to manipulate the data
     * stream before writing it
     * modify this to suit your data array
     * @access  private
     * @param   (array)     $data           associative array representing
     *                                      a tabular worksheet
     */
    function _xls_stream_write($data)
    {
        if (is_array($data) && !empty($data))
        {
            $row = 0;
            foreach (array_values($data) as $_data)
            {
                if (is_array($_data) && !empty($_data))
                {
                    if ($row == 0)
                    {
                        // write the column headers
                        foreach (array_keys($_data) as $col => $val)
                        {
                            // next line intentionally commented out
                            // since we don't want a warning about the
                            // extra bytes written
                            // $size += $this->write($row, $col, $val);
                            $this->_xlsWriteCell($row, $col, $val);
                        }
                        $row++;
                    }

                    foreach (array_values($_data) as $col => $val)
                    {
                        $size += $this->_xlsWriteCell($row, $col, $val);
                    }
                    $row++;
                }
            }
        }
        return $size;
    }

    /**
     * Excel worksheet cell insertion
     * (single-worksheet supported only)
     * @access  private
     * @param   (int)       $row            worksheet row number (0...65536)
     * @param   (int)       $col            worksheet column number (0..255)
     * @param   (mixed)     $val            worksheet row number
     */
    function _xlsWriteCell($row, $col, $val)
    {
        if (is_float($val) || is_int($val))
        {
            // doubles, floats, integers
            $str  = pack(str_repeat($this->bin[$this->endian], 5), 0x203, 14, $row, $col, 0x0);
            $str .= pack("d", $val);
        }
        else
        {
            // everything else is treated as a string
            $l    = strlen($val);
            $str  = pack(str_repeat($this->bin[$this->endian], 6), 0x204, 8 + $l, $row, $col, 0x0, $l);
            $str .= $val;
        }
        fwrite($this->fp, $str);
        $this->position += strlen($str);
        return strlen($str);
    }

    /**
     * called by an fclose() on the stream
     */
    function stream_close()
    {
        if (preg_match("/^w|x/", $this->mode))
        {
            // flush the buffer
            $bufsize = $this->_xls_stream_write(unserialize($this->buffer));

            // ...and empty it
            $this->buffer = null;

            // write the xls EOF
            $str = pack(str_repeat($this->bin[$this->endian], 2), 0x0A, 0x00);
            $this->position += strlen($str);
            fwrite($this->fp, $str);
        }

        // ...and close the internal stream
        return fclose($this->fp);
    }

    function stream_eof()
    {
        $eof = true;
        if (is_resource($this->fp))
        {
            $eof = feof($this->fp);
        }
        return $eof;
    }
}

stream_wrapper_register("xlsfile", "xlsStream")
    or die("Failed to register protocol: xlsfile");
?>

 

EDIT: Please use [code][/code] tags!

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.