value = $value; } } /** * Ряд таблицы */ class TableRow { public $style = false; public $cells = array(); public $height = false; function setCell($y, $value) { $this->cells[$y] = new TableCell($value); } function setCellStyle($y, $name) { $this->cells[$y]->style = $name; } } /** * Таблица */ class Excel_Table { static $index; private $name; private $style; protected $rows = array(); protected $_splitVertical = false; protected $_splitHorizontal = false; function __construct() { $this->name = "Page " . intval(self::$index ++); } /** * Записать значение в клетку с заданными координатами */ function setCell($x, $y, $value) { assert(is_numeric($x) && $x > 0); assert(is_numeric($y) && $y > 0); if(! isset($this->rows[$x])) { $this->rows[$x] = new TableRow(); } $row/*: TableRow*/ = $this->rows[$x]; $row->setCell($y, $value); } /** * Заполняет ряд начиная с указанного столбца значениями из массива */ function setRow($row, $index, array $data) { assert(is_numeric($index) && $index > 0); assert(is_numeric($row) && $row > 0); reset($data); for ($i = $index; $i < $index + count($data); $i++) { $this->setCell($row, $i, current($data)); next($data); } } /** * Устанавливает высоту ряда * @param $row integer Номер ряда * @parma $value real Высота ряда */ function setRowHeight ($row, $value) { assert(is_numeric($row) && $row > 0); $this->rows[$row]->height = $value; } /** * Устанавливает стиль ряда * @param $row integer Номер ряда * @parma $name string Имя стиля */ function setRowStyle ($row, $name) { assert(is_numeric($row) && $row > 0); $this->rows[$row]->style = $name; } /** * Обьединяет клетки в строке * @param $row Номер ряда * @param $cell Номер столбца * @param $merge Количество клеток для обьединения */ function setCellMerge($x, $cell, $merge) { assert(is_numeric($x) && $x > 0); assert(is_numeric($cell) && $cell > 0); $row/*: TableRow*/ = $this->rows[$x]; $row->cells[$cell]->merge = $merge; } /** * Устанавливает стиль для клеток ряда * @param $row integer Номер ряда * @param $y integer Номер столбца * @parma $name string Имя стиля */ function setCellStyle ($row, $y, $name) { if (isset($this->rows[$row])) $this->rows[$row]->setCellStyle($y, $name); } /** * Добавляет строку к таблице */ function addRow($index = 1, array $data = array("")) { assert(is_numeric($index) && $index > 0); $offset = $this->getRows() + 1; $this->setRow($offset, $index, $data); return $offset; } /** * Количество строк в таблице * * @return int */ function getRows() { $keys/*: array*/ = array_keys($this->rows); return max($keys); } /** * Количество столбцов в строке * * @return int */ function getRowCells(TableRow $row) { $keys/*: array*/ = array_keys($row->cells); return max($keys); } /** * Разделяет таблицу на две части по вертикали * @param $n integer Количество столбцов слева */ function splitVertical($n) { $this->_splitVertical = $n; } /** * Разделяет таблицу на две части по горизонтали * @param $n integer Количество столбцов сверху */ function splitHorizontal($n) { $this->_splitHorizontal = $n; } /** * Количество столбцов в таблице * * @return int */ function getColumns() { return max(array_map(array($this, 'getRowCells'), $this->rows)); } function encode($s) { return $s; } /** * Генерация клетки таблицы (Переработать) */ function createCell (TableCell $ncell, XMLWriter $doc, $j, $value/*: any*/, $setIndex) { $doc->startElement("Cell"); if ($ncell->style) { $doc->writeAttribute('ss:StyleID', $ncell->style); } if ($ncell->merge) { $doc->writeAttribute('ss:MergeAcross', $ncell->merge); } if ($setIndex) { $doc->writeAttribute('ss:Index', $j); } $doc->startElement("Data"); if ($value instanceof Excel_DateTime) { $doc->writeAttribute('ss:Type', "DateTime"); $doc->text($value->getString()); } else if ($value instanceof Excel_Number) { $doc->writeAttribute('ss:Type', "Number"); $doc->text($value->getString()); } else { if (is_string($value)) { $doc->writeAttribute('ss:Type', "String"); } else { $doc->writeAttribute('ss:Type', "Number"); } $doc->writeCData($this->encode($value)); } $doc->endElement(); $doc->endElement(); } /** * Генерация таблицы */ public function createTable (XMLWriter $doc) { $doc->startElement('Worksheet'); $doc->writeAttribute('ss:Name', $this->name); $columns = $this->getColumns(); $rows = $this->getRows(); $doc->startElement('Table'); $doc->writeAttribute('ss:ExpandedColumnCount', $columns); $doc->writeAttribute('ss:ExpandedRowCount', $rows); // Переписать цыкл !!!!!!! for ($i = 1; $i <= $rows; $i++) { $doc->startElement('Row'); if (isset($this->rows[$i])) { if ($this->rows[$i]->style) { $doc->writeAttribute('ss:StyleID', $this->rows[$i]->style); } if ($this->rows[$i]->height) { $doc->writeAttribute('ss:Height', $this->rows[$i]->height); } $nrow/*: TableRow*/ = $this->rows[$i]; // Флаг индикатор подстановки номера столбца $setIndex = false; for ($j = 1; $j <= $columns; $j++) { $value = null; if (isset($nrow->cells[$j])) { $value = $nrow->cells[$j]->value; } if (!empty($value)) { $this->createCell($nrow->cells[$j], $doc, $j, $value, $setIndex); $setIndex = false; } else { $setIndex = true; } } } $doc->endElement(); } $doc->endElement(); $this->splitPane ($doc); $doc->endElement(); } protected function splitPane (XMLWriter $doc) { $doc->startElement('WorksheetOptions'); $doc->writeAttribute('xmlns', 'urn:schemas-microsoft-com:office:excel'); $doc->writeElement('FrozenNoSplit'); if ($this->_splitVertical) { $doc->writeElement('SplitVertical', $this->_splitVertical); $doc->writeElement('LeftColumnRightPane', $this->_splitVertical); } if ($this->_splitHorizontal) { $doc->writeElement('SplitHorizontal', $this->_splitHorizontal); $doc->writeElement('TopRowBottomPane', $this->_splitHorizontal); } if ($this->_splitHorizontal && $this->_splitVertical) { $doc->writeElement('ActivePane', 0); } else if($this->_splitHorizontal) { $doc->writeElement('ActivePane', 2); } $doc->endElement(); } }