Я использую библиотеку PHPExcel 1.7.9
для работы с файлами Excel
. Во-первых, я создаю шаблон, стилю и отполирую его. Затем, чтобы избежать жесткого кодирования стиля, используя указанную выше библиотеку, я открываю этот шаблон, изменяю некоторые значения и сохраняю их как новый .xlsx
файл.
Сначала мы получаем этот стиль из ячеек.
$this->styles = array() ; $this->styles['category'] = $sheet->getStyle("A4"); $this->styles['subcategory'] = $sheet->getStyle("A5");
Вот рекурсивная функция, которая отображает категории и подкатегории.
private function displayCategories($categories, &$row, $level = 0){ $sheet = $this->content ; foreach($categories as $category){ if ($category->hasChildren() || $category->hasItems()){ //Check if the row has changed. $sheet->getRowDimension($row)->setRowHeight(20); $sheet->mergeCells(Cell::NUMBER . $row . ":" . Cell::TOTAL . $row) ; $name = ($level == 0) ? strtoupper($category->name) : str_repeat(" ", $level*6) ."- {$category->name}" ; $sheet->setCellValue(Cell::NUMBER . $row, $name) ; $sheet->duplicateStyle((($level == 0) ? $this->styles['category'] : $this->styles['subcategory']), Cell::NUMBER . $row); $row++ ; if ($category->hasChildren()){ $this->displayCategories($category->children, $row, $level+1); } } } }
Проблема
Если используется $sheet->duplicateStyle()
, невозможно будет сохранить документ из-за бесконечной рекурсии.
Максимальный уровень гнездования функции «200» достигнут, прерывается! <- FATAL ERROR
Проблема заключается в следующем фрагменте кода, внутри класса PHPExcel_Style_Fill
, один объект снова и снова ссылается на себя.
public function getHashCode() { //class PHPExcel_Style_Fill if ($this->_isSupervisor) { var_dump($this === $this->getSharedComponent()); //Always true 200 times return $this->getSharedComponent()->getHashCode(); } return md5( $this->getFillType() . $this->getRotation() . $this->getStartColor()->getHashCode() . $this->getEndColor()->getHashCode() . __CLASS__ ); }
Есть ли способ обхода решения? Я также принимаю любые идеи о том, как применять полный стиль одной ячейки к другой.
Решение:
Как сказал @MarkBaker в комментариях, ветвь develop
на GitHub действительно содержит исправления к ошибке.
EDIT Я добавил запрос на перенос с исправлением: https://github.com/PHPOffice/PHPExcel/pull/251
Это происходит, когда вы пытаетесь дублировать стиль ячейки в одной и той же ячейке; Взгляните на это:
$phpe = new PHPExcel(); $sheet = $phpe->createSheet(); $sheet->setCellValue('A1', 'hi there') ; $sheet->setCellValue('A2', 'hi again') ; $sheet->duplicateStyle($sheet->getStyle('A1'), 'A2'); $writer = new PHPExcel_Writer_Excel2007($phpe); $writer->save('./test.xlsx');
Все будет хорошо. НО, если я добавлю еще одну строку:
$sheet->duplicateStyle($sheet->getStyle('A1'), 'A1');
то bang, бесконечная рекурсия начинается после вызова метода save
Чтобы исправить ваш код, вы должны изменить эту часть:
$sheet->duplicateStyle((($level == 0) ? $this->styles['category'] : $this->styles['subcategory']), Cell::NUMBER . $row);
Что-то вроде:
$style = ($level == 0) ? $this->styles['category'] : $this->styles['subcategory']; $targetCoords = Cell::NUMBER . $row; if($style->getActiveCell() != $targetCoords) { $sheet->duplicateStyle($style, $targetCoords); }
Не зная специфики библиотеки …
Как насчет изменения этого:
public function getHashCode() { //class PHPExcel_Style_Fill if ($this->_isSupervisor) {
К этому:
public function getHashCode() { //class PHPExcel_Style_Fill if ($this->_isSupervisor && ( $this != $this->getSharedComponent() ) ) {
Если логика хэш-кода после оператора if
не применяется к _isSupervisor
, добавьте еще один логический оператор и верните фиксированное значение, например:
public function getHashCode() { //class PHPExcel_Style_Fill if ($this->_isSupervisor) { if ( $this == $this->getSharedComponent() ) return md5(0);