Created
September 3, 2014 13:44
-
-
Save markvds/2b5161063557a850b073 to your computer and use it in GitHub Desktop.
Excel Writer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Simple excel generating from PHP5 | |
* | |
* @package Utilities | |
* @license http://www.opensource.org/licenses/mit-license.php | |
* @author Oliver Schwarz <[email protected]> | |
* @version 1.0 | |
*/ | |
/** | |
* Generating excel documents on-the-fly from PHP5 | |
* | |
* Uses the excel XML-specification to generate a native | |
* XML document, readable/processable by excel. | |
* | |
* Modified by Mark van der Sanden, Magentics | |
*/ | |
class Mgcs_General_Model_Excel_Writer | |
{ | |
/** | |
* Header (of document) | |
* @var string | |
*/ | |
private $_header = ''; | |
/** | |
* Footer (of document) | |
* @var string | |
*/ | |
private $_footer = ''; | |
/** | |
* Lines to output in the excel document | |
* @var array | |
*/ | |
private $_lines = array(); | |
private $_htmlLines = array(); | |
/** | |
* Used encoding | |
* @var string | |
*/ | |
private $_encoding; | |
/** | |
* Worksheet title | |
* @var string | |
*/ | |
private $_worksheetTitle; | |
protected $_styles = array( | |
'shorttime' => '<NumberFormat ss:Format="Short Time"/>', | |
'shortdate' => '<NumberFormat ss:Format="Short Date"/>', | |
'generaldate' => '<NumberFormat ss:Format="General Date"/>', | |
'euro' => '<NumberFormat ss:Format="_ "€"\ * #,##0.00_ ;_ "€"\ * \-#,##0.00_ ;_ "€"\ * "-"??_ ;_ @_ "/>', | |
); | |
/** | |
* Constructor | |
* | |
* The constructor allows the setting of some additional | |
* parameters so that the library may be configured to | |
* one's needs. | |
* | |
* On converting types: | |
* When set to true, the library tries to identify the type of | |
* the variable value and set the field specification for Excel | |
* accordingly. Be careful with article numbers or postcodes | |
* starting with a '0' (zero)! | |
* | |
* @param string $sEncoding Encoding to be used (defaults to UTF-8) | |
* @param boolean $bConvertTypes Convert variables to field specification | |
* @param string $sWorksheetTitle Title for the worksheet | |
*/ | |
public function __construct($encoding = 'UTF-8', $worksheetTitle = 'Table1') | |
{ | |
$this->setEncoding($encoding ? $encoding : 'UTF-8'); | |
$this->setWorksheetTitle($worksheetTitle); | |
$this->_header = | |
'<?xml version="1.0" encoding="%s"?>' . "\n" . | |
'<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">' . "\n" . | |
' <Styles>' . "\n"; | |
foreach ($this->_styles as $name => $style) { | |
$this->_header .= ' <Style ss:ID="' . $name . '">' . $style . '</Style>' . "\n"; | |
} | |
$this->_header .= | |
' </Styles>' . "\n" | |
; | |
$this->_footer = | |
'</Workbook>' | |
; | |
} | |
/** | |
* Set encoding | |
* @param string Encoding type to set | |
*/ | |
public function setEncoding($sEncoding) | |
{ | |
$this->_encoding = $sEncoding; | |
} | |
/** | |
* Set worksheet title | |
* | |
* Strips out not allowed characters and trims the | |
* title to a maximum length of 31. | |
* | |
* @param string $title Title for worksheet | |
*/ | |
public function setWorksheetTitle ($title) | |
{ | |
$title = preg_replace ("/[\\\|:|\/|\?|\*|\[|\]]/", "", $title); | |
$title = substr ($title, 0, 31); | |
$this->_worksheetTitle = $title; | |
} | |
/** | |
* Adds a single row to the document | |
* | |
* The values can be a scalar value or array. Scalar values get | |
* added as string, array can have the following keys: | |
* - style: one of the keys in $this->_styles (shortdate, shorttime, generaldate, euro) | |
* - type: case insensitive Excel type (string, number, date, datetime, ...) | |
* | |
* Excel types: | |
* - String Hello | |
* - Number 123.12 | |
* - Date 2010-02-03 | |
* - DateTime 1999-05-31T13:20:00Z-05:00 | |
* - Time 13:20:00, 13:20:00Z-05:00 | |
* - anyURI http://www.example.com/ | |
* - Boolean true, false, 1, 0 | |
* - Integer -1, 1234 | |
* - Double 1.23, 1.876, 12.78E-2 | |
* | |
* @see http://msdn.microsoft.com/en-us/library/aa203732%28office.11%29.aspx | |
* @param array $array Array with cell values | |
* @return void | |
*/ | |
public function addRow($array) | |
{ | |
$types = array( | |
'String', 'Number', 'Date', 'DateTime', 'Time', | |
'anyURI', 'Boolean','Integer', 'Double' | |
); | |
$cells = ''; | |
$htmlCells = ''; | |
foreach ($array as $value) { | |
$type = 'String'; | |
$style = ''; | |
$htmlStyle = ''; | |
if (is_array($value)) { | |
if (!empty($value['type'])) { | |
$value['type'] = strtolower($value['type']); | |
foreach ($types as $_type) { | |
if ($value['type'] == strtolower($_type)) { | |
$type = $_type; | |
} | |
} | |
} | |
if (!empty($value['style'])) { | |
$value['style'] = strtolower($value['style']); | |
foreach (array_keys($this->_styles) as $_style) { | |
if ($value['style'] == strtolower($_style)) { | |
$style = $_style; | |
} | |
} | |
} | |
if (isset($value['value'])) { | |
$value = $value['value']; | |
} else { | |
$value = ''; | |
} | |
} else { | |
// kept for compatibility reasons | |
if (preg_match('/^##([a-z]{1,15})(\|[a-z]{1,15})?:(.*)/i', $value, $matches)) { | |
$type = $matches[1]; | |
$value = $matches[3]; | |
if (!empty($matches[2])) { | |
$style = substr($matches[2], 1); | |
} | |
} | |
} | |
switch ($type) { | |
case 'Number': | |
case 'Integer': | |
case 'Double': | |
$htmlStyle = 'text-align: right;'; | |
break; | |
} | |
if ($type == 'DateTime' && preg_match('/[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}/', $value)) { | |
$value = date('Y-m-d\TH:i:s', strtotime($value)); | |
} | |
if ($type == 'DateTime' && preg_match('/^[0-9]+$/', $value)) { | |
$value = date('Y-m-d\TH:i:s', $value); | |
} | |
$styleDeclaration = ''; | |
if ($style) { | |
$styleDeclaration = ' ss:StyleID="' . $style . '"'; | |
} | |
$cells .= '<Cell' . $styleDeclaration . '><Data ss:Type="' . htmlspecialchars($type, ENT_COMPAT, $this->_encoding) . '">' . htmlentities($value, ENT_COMPAT, $this->_encoding) . '</Data></Cell>' . "\n"; | |
$htmlCells .= '<td ' . ($htmlStyle ? sprintf('style="%s"', htmlspecialchars($htmlStyle)) : '') . '>' . htmlentities($value) . '</td>' . "\n"; | |
} | |
$this->_lines[] = "<Row>\n" . $cells . "</Row>\n"; | |
$this->_htmlLines[] = '<tr>' . $htmlCells . '</tr>' . "\n"; | |
} | |
/** | |
* Add an array to the document | |
* @param array 2-dimensional array | |
*/ | |
public function addArray ($array) | |
{ | |
foreach ($array as $row) { | |
$this->addRow($row); | |
} | |
} | |
/** | |
* Generate the excel file | |
* @param string $filename Name of excel file to generate (...xls) | |
*/ | |
public function getXML() | |
{ | |
// print out document to the browser | |
// need to use stripslashes for the damn ">" | |
$output = ''; | |
$output .= stripslashes(sprintf($this->_header, $this->_encoding)); | |
$output .= "\n<Worksheet ss:Name=\"" . $this->_worksheetTitle . "\">\n<Table>\n"; | |
foreach ($this->_lines as $line) { | |
$output .= $line; | |
} | |
$output .= "</Table>\n</Worksheet>\n"; | |
$output .= $this->_footer; | |
return $output; | |
} | |
public function stream($filename = 'document.xml') | |
{ | |
// correct/validate filename | |
$filename = basename(preg_replace('/[^aA-zZ0-9\_\.-]/', '', $filename)); | |
// deliver header (as recommended in php manual) | |
header("Content-Type: application/vnd.ms-excel; charset=" . $this->_encoding); | |
header("Content-Disposition: attachment; filename=\"" . $filename . "\""); | |
echo $this->getXML(); | |
} | |
public function write($filename = 'excel-export.xml') | |
{ | |
file_put_contents($filename, $this->getXML()); | |
} | |
/** | |
* Generate and stream or save the xml | |
* | |
* Kept for compatibility reasons | |
* | |
* @deprecated | |
* @param string $filename | |
* @param bool $stream | |
*/ | |
public function generateXML($filename = 'excel-export', $stream = true) | |
{ | |
if ($stream) { | |
return $this->stream($filename); | |
} else { | |
return $this->write($filename); | |
} | |
} | |
public function getHtml($firstRowIsHeader = true) | |
{ | |
$html = '<table>' . "\n"; | |
foreach ($this->_htmlLines as $line) { | |
$html .= $line; | |
} | |
$html .= '</table>' . "\n"; | |
return $html; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment