diff --git a/Excel_Xml.php b/Excel_Xml.php new file mode 100644 index 0000000..3ab4fa7 --- /dev/null +++ b/Excel_Xml.php @@ -0,0 +1,295 @@ + + * @license MIT License http://www.opensource.org/licenses/mit-license.php + * @version 2.0 + * @link http://code.google.com/p/php-excel/ + * + * @todo Add compatibility methods for version 1.0 + * @todo Add method to write to file + * @todo Add method to return output + */ + +/** + * Excel Xml Generator Class + * + * A simple class to dump an array into a file or output stream + * readable by Excel or other calc/spreadsheet software. + * + * @category Utilities + * @package Utilities + * @author Oliver Schwarz + * @license MIT license http://www.opensource.org/licenses/mit-license.php + * @version 2.0 + * @link http://code.google.com/p/php-excel/ + */ +class Excel_Xml +{ + /** + * Microsoft Open XML header for spreadsheets + * @var string + * @static + */ + const HEADER = "\n"; + + /** + * Microsoft Open Xml closing tag + * @var string + * @static + */ + const FOOTER = ''; + + /** + * Worksheet data + * @var array + */ + protected $aWorksheetData; + + /** + * Output string + * @var string + */ + protected $sOutput; + + /** + * Encoding + * @var string + */ + protected $sEncoding; + + /** + * Get sanitized workbook title + * + * Sanitizes a workbook title (filename) to contain only the + * allowed characters using a whitelist regexp. + * + * @param string $title Title to sanitize + * + * @return string Sanitized workbook title + */ + private function _getSanitizedWorkbookTitle($title) + { + return preg_replace('/[^aA-zZ0-9\_\-\.]/', '', $title); + } + + /** + * Get sanitized worksheet title + * + * Sanitizes a worksheet title using a whitelist regexp. + * Excel only allows certain characters and only a certain + * length in worksheet titles. + * + * @param string $title Title to sanitize + * + * @return string Sanitized worksheet title + */ + private function _getSanitizedWorksheetTitle($title) + { + $sWorksheetTitle = preg_replace('/[\\\|:|\/|\?|\*|\[|\]]/', '', $title); + return substr($sWorksheetTitle, 0, 31); + } + + /** + * Generate workbook + * + * Generates the outer workbook frame to contain multiple worksheets. + * Expects to have all required sheets as data already in the + * $aWorksheetData container. + * + * @uses $aWorksheetData + * @uses generateWorksheet() + * + * @return void + */ + protected function generateWorkbook() + { + $this->sOutput = stripslashes(sprintf(self::HEADER, $this->sEncoding))."\n"; + foreach ($this->aWorksheetData as $aSheet) { + $this->generateWorksheet($aSheet); + } + + $this->sOutput .= self::FOOTER; + } + + /** + * Generate worksheet + * + * Generates a single worksheet into the output container. + * + * @param array $aSheet Array with sheet data + * + * @uses generateRow() + * @todo Check whether the row restriction is still necessary + * @return void + */ + protected function generateWorksheet($aSheet) + { + $this->sOutput .= sprintf("\n \n", $aSheet['title']); + if (count($aSheet['data'])) { + $aSheet['data'] = array_slice($aSheet['data'], 0, 65536); + foreach ($aSheet['data'] as $k => $v) { + $this->generateRow($v); + } + } + + $this->sOutput .= "
\n
\n"; + } + + /** + * Generate row + * + * Generates a single row in the worksheet. + * + * @param array $row Row item with data + * + * @uses generateCell() + * @return void + */ + protected function generateRow($row) + { + $this->sOutput .= " \n"; + foreach ($row as $k => $v) { + $this->generateCell($v); + } + + $this->sOutput .= " \n"; + } + + /** + * Generate single cell + * + * This is where all the magic happens. Generates the cell from the given + * input. + * + * @param string $cell Cell data + * + * @return void + */ + protected function generateCell($cell) + { + // set default type + $type = 'String'; + $cell = str_replace(''', ''', htmlspecialchars($cell, ENT_QUOTES)); + $this->sOutput .= sprintf(" %s\n", $type, $cell); + } + + /** + * Constructor + * + * Sets default property values and allows to configure + * the used encoding. If a certain encoding is used, Excel_Xml + * expects all other input in this encoding. + * + * @param string $sEncoding Encoding to use (default UTF-8) [optional] + * + * @return void + */ + public function __construct($sEncoding = 'UTF-8') + { + $this->sEncoding = $sEncoding; + $this->sOutput = ''; + } + + /** + * Add a worksheet + * + * Adds a new worksheet to the data container. + * + * @param string $title Title of worksheet + * @param array $data Two-dimensional array of data + * + * @return void + */ + public function addWorksheet($title, $data) + { + $this->aWorksheetData[] = array( + 'title' => $this->_getSanitizedWorksheetTitle($title), + 'data' => $data + ); + } + + /** + * Send workbook to browser + * + * Sends the workbook to the browser opening the default "Save as..." + * dialog by using PHP's header directive. + * + * @param string $filename Filename to use in dialog + * + * @return void + */ + public function sendWorkbook($filename) + { + if (!preg_match('/\.(xml|xls)$/', $filename)) { + throw new InvalidArgumentException('Filename mimetype must be .xml or .xls'); + } + $filename = $this->_getSanitizedWorkbookTitle($filename); + $this->generateWorkbook(); + if (preg_match('/\.xls$/', $filename)) { + header("Content-Type: application/vnd.ms-excel; charset=" . $this->sEncoding); + header("Content-Disposition: inline; filename=\"" . $filename . "\""); + } else { + header("Content-Type: application/xml; charset=" . $this->sEncoding); + header("Content-Disposition: attachment; filename=\"" . $filename . "\""); + } + echo $this->sOutput; + } + + /** + * Write workbook to file + * + * Writes the workbook into the file/path given as a parameters. + * The method checks whether the directory is writable and the + * file is not existing and writes the file. + * + * @param string $filename Filename to use for writing (must contain mimetype) + * + * @return string Message + */ + public function writeWorkbook($filename) + { + $this->generateWorkbook(); + $filename = $this->_getSanitizedWorkbookTitle($filename); + if (!$handle = @fopen($filename, 'w+')) { + throw new Exception(sprintf("Not allowed to write to file %s", $filename)); + } + if (@fwrite($handle, $this->sOutput) === false) { + throw new Exception(sprintf("Error writing to file %s", $filename)); + } + @fclose($handle); + return sprintf("File %s written", $filename); + } + + /** + * Get workbook + * + * Returns the generated workbook. + * + * @return string Generated workbook XML + */ + public function getWorkbook() + { + $this->generateWorkbook(); + return $this->sOutput; + } + + /** + * Destructor + * + * The worksheet may contain some massive amount of data. The deconstructor + * frees some of the memory again. + * + * @return void + */ + public function __destruct() + { + unset($this->aWorksheetData); + unset($this->sOutput); + } + +} \ No newline at end of file diff --git a/examples/download_workbook.php b/examples/download_workbook.php new file mode 100644 index 0000000..3d3fe52 --- /dev/null +++ b/examples/download_workbook.php @@ -0,0 +1,18 @@ +addWorksheet('Worksheet test', $data); +$phpexcel->addWorksheet('Worksheet test 2', $data_sec); +$phpexcel->sendWorkbook('openoffice-test.xml'); \ No newline at end of file diff --git a/license.txt b/license.txt deleted file mode 100644 index fc721ab..0000000 --- a/license.txt +++ /dev/null @@ -1,24 +0,0 @@ -The MIT License - -Copyright (c) 2007 Oliver Schwarz - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/php-excel.class.php b/php-excel.class.php deleted file mode 100644 index 02d2f5d..0000000 --- a/php-excel.class.php +++ /dev/null @@ -1,175 +0,0 @@ - - * @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. - * - * @package Utilities - * @subpackage Excel - * @author Oliver Schwarz - * @version 1.1 - * - * @todo Issue #4: Internet Explorer 7 does not work well with the given header - * @todo Add option to give out first line as header (bold text) - * @todo Add option to give out last line as footer (bold text) - * @todo Add option to write to file - */ -class Excel_XML -{ - - /** - * Header (of document) - * @var string - */ - private $header = "\n"; - - /** - * Footer (of document) - * @var string - */ - private $footer = ""; - - /** - * Lines to output in the excel document - * @var array - */ - private $lines = array(); - - /** - * Used encoding - * @var string - */ - private $sEncoding; - - /** - * Convert variable types - * @var boolean - */ - private $bConvertTypes; - - /** - * Worksheet title - * @var string - */ - private $sWorksheetTitle; - - /** - * 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($sEncoding = 'UTF-8', $bConvertTypes = false, $sWorksheetTitle = 'Table1') - { - $this->bConvertTypes = $bConvertTypes; - $this->setEncoding($sEncoding); - $this->setWorksheetTitle($sWorksheetTitle); - } - - /** - * Set encoding - * @param string Encoding type to set - */ - public function setEncoding($sEncoding) - { - $this->sEncoding = $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->sWorksheetTitle = $title; - } - - /** - * Add row - * - * Adds a single row to the document. If set to true, self::bConvertTypes - * checks the type of variable and returns the specific field settings - * for the cell. - * - * @param array $array One-dimensional array with row content - */ - private function addRow ($array) - { - $cells = ""; - foreach ($array as $k => $v): - $type = 'String'; - if ($this->bConvertTypes === true && is_numeric($v)): - $type = 'Number'; - endif; - $v = htmlentities($v, ENT_COMPAT, $this->sEncoding); - $cells .= "" . $v . "\n"; - endforeach; - $this->lines[] = "\n" . $cells . "\n"; - } - - /** - * Add an array to the document - * @param array 2-dimensional array - */ - public function addArray ($array) - { - foreach ($array as $k => $v) - $this->addRow ($v); - } - - - /** - * Generate the excel file - * @param string $filename Name of excel file to generate (...xls) - */ - public function generateXML ($filename = 'excel-export') - { - // correct/validate filename - $filename = preg_replace('/[^aA-zZ0-9\_\-]/', '', $filename); - - // deliver header (as recommended in php manual) - header("Content-Type: application/vnd.ms-excel; charset=" . $this->sEncoding); - header("Content-Disposition: inline; filename=\"" . $filename . ".xls\""); - - // print out document to the browser - // need to use stripslashes for the damn ">" - echo stripslashes (sprintf($this->header, $this->sEncoding)); - echo "\nsWorksheetTitle . "\">\n\n"; - foreach ($this->lines as $line) - echo $line; - - echo "
\n
\n"; - echo $this->footer; - } - -} - -?> \ No newline at end of file diff --git a/readme.txt b/readme.txt deleted file mode 100644 index 4f20dae..0000000 --- a/readme.txt +++ /dev/null @@ -1,90 +0,0 @@ -PHP-Excel -========= -This is a small library written in PHP to generate an Excel -file (in MicrosoftXML format) out of a two-dimensional array. -It is NOT a full-grown solution to handle some serious data -interchange between databases <> PHP <> Excel, but a small -and simple way of throwing out an XML natively readable by -Excel to the browser. - -Author: Oliver Schwarz -Project: http://code.google.com/p/php-excel/ -Issues: http://code.google.com/p/php-excel/issues/list -Version: 1.1 - -Version 1.1 ------------ -After revitalizing the project this version now addresses -several issues in the bugtracker. On my way to version 2 -I wanted to publish an intermediate version to fix some -stupid errors I did in the first run. - -Version 2 now allows: -* The setting of an encoding (default: UTF-8) -* The automagic type identification for strings/numbers - -It fixes: -* An issue (#3) with large arrays and implode -* An issue (#7) with other charsets than iso-8859-1 -* An issue (#9) with XML entity encoding (still not 100%) - -Version 1 ---------- -This was the first version, released on March, 8th 2007. It -was usable for many people using the ISO-8859-1 charset and -for small arrays. However, it had some serious flaws using -other charsets or using larger data containers. - -License -------- -Please see the included license.txt for details (it's MIT -license) or visit: -http://www.opensource.org/licenses/mit-license.php - -...for more details. - -Tutorial --------- -To get the export running, first create a two-dimensional -array (please stick to 2 dimensions, the library does not -work with complex arrays): - -$a = array(); -for($i=0;$i<10;$i++) - $a[] = array('Cell' . $i); - -Instanciate the library and give the array as input: - -$xls = new Excel_XML(); -$xls->addArray($a); - -Generate the XML/Excel file. This method should trigger -the browsers "Save as..." dialog: - -$xls->generateXML('test'); - -Optional values ---------------- -1) You may set your own charset in the constructor of -the class: - -$xls = new Excel_XML('UTF-8'); - -2) You may activate/deactivate type identification for -table cells (strings/numbers): - -$xls = new Excel_XML('UTF-8', true); - -Whereas the values are: 'true' = type identification -active, 'false' (default) = type identification inactive. - -3) You may set the worksheet title directly in the -constructor: - -$xls = new Excel_XML('UTF-8', true, 'Testsheet'); - -Problems, Errors, Help ----------------------- -If problems or error occur I unfortunately can not provide -any support. However, please visit the projects website and -post an issue to the comments or bugtracker. Thanks. \ No newline at end of file diff --git a/test.php b/test.php deleted file mode 100644 index 0f5d45e..0000000 --- a/test.php +++ /dev/null @@ -1,18 +0,0 @@ - array ('Name', 'Surname'), - array('Schwarz', 'Oliver'), - array('Test', 'Peter') - ); - -// generate file (constructor parameters are optional) -$xls = new Excel_XML('UTF-8', false, 'My Test Sheet'); -$xls->addArray($data); -$xls->generateXML('my-test'); - -?> \ No newline at end of file