Показаны сообщения с ярлыком PHPExcel. Показать все сообщения
Показаны сообщения с ярлыком PHPExcel. Показать все сообщения

пятница, 1 февраля 2019 г.

PHPExcel опять проблемы с чтением файла

Так уж получилось, что до сих пор пользуюсь закопанным проектом PHPExcel

И сегодня пилю импортер под непонятного поставщика, файл xlsx, если его пересохранить в офисе, то нормально читается, а исходный же файл не читается, выдает вот такую ошибку

Fatal error: Uncaught PHPExcel_Exception: Cell coordinate can not be zero-length string in PHPEXCEL/PHPExcel/Cell.php:591

Ну полез я по цепочке вызовов, понял что в какой то момент идет вызов
PHPExcel_Cell::coordinateFromString($r)
где $r - пустая строка...

В файле PHPExcel/Reader/Excel2007.php на 818 строке находим строку с получением координат, перед ней дописываем строчку 

if ($r=="") continue;

 Получаем в итоге такое










Данные читаются вполне идеально, просто видимо генератор этого файла у поставщика дал сбой и дописал данные, которые не имеют ячейки, с таким фиксом левые ячейки без адресов просто отсекаются, оставляя полезные данные... 


Если кому интересна моя пропатченная версия PHPExcel, адекватно читающая и генерирующая разные файлы на PHP7.2 - могу выложить, но так вообще лучше пользоваться продолжением этого проекта - PhpSpreadshee, PHPExcel уже заброшенный проект с кучей недоработок...

среда, 31 января 2018 г.

PHPExcel 1.8 - getAllBorders bug - не выделяются границы

В общем дело происходило вот так

$Sheet->getStyle('A5:E9')->getBorders()
->getAllBorders()
->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);

Но я перенес свой проектик с php5.4 на 7.1 и у меня очень много ошибок начало вылазить, не долго думая, решил обновить PHPExcel 1.7.6 -> 1.8, после обновления, у меня перестали применяться стили к границам ячеек.

Ну я залез в файл PHPExcel/Style/Border.php
и на 141 строке нашел функцию getStyleArray

public function getStyleArray($array)
    {
        switch ($this->parentPropertyName) {
            case 'allBorders':
            case 'bottom':
            case 'diagonal':
            case 'horizontal':
            case 'inside':
            case 'left':
            case 'outline':
            case 'right':
            case 'top':
            case 'vertical':
                $key = strtolower('vertical');
                break;
        }
        return $this->parent->getStyleArray(array($key => $array));
    }


Смешно, да?
При любом положении bottom, diagonal... у нас будет vertical.

Теперь обратимся к более ранней версии этой функции (1.7.6)

public function getStyleArray($array)
    {
        switch ($this->_parentPropertyName) {
        case '_allBorders':
            $key = 'allborders';
            break;

        case '_bottom':
            $key = 'bottom';
            break;

        case '_diagonal':
            $key = 'diagonal';
            break;

        case '_horizontal':
            $key = 'horizontal';
            break;

        case '_inside':
            $key = 'inside';
            break;

        case '_left':
            $key = 'left';
            break;

        case '_outline':
            $key = 'outline';
            break;

        case '_right':
            $key = 'right';
            break;

        case '_top':
            $key = 'top';
            break;

        case '_vertical':
            $key = 'vertical';
            break;
        }
        return $this->_parent->getStyleArray(array($key => $array));
    }



Т.е. в старой версии к нам приходили значения с префиксом _, а на выходе без префикса, в новой версии библиотеки перепилили всё и входные стали без префикса, но разработчики немного были невнимательными и хотели сказать что-то вроде такого:
public function getStyleArray($array)
    {
        switch ($this->parentPropertyName) {
            case 'allBorders':
            case 'bottom':
            case 'diagonal':
            case 'horizontal':
            case 'inside':
            case 'left':
            case 'outline':
            case 'right':
            case 'top':
            case 'vertical':
                $key = strtolower(
$this->parentPropertyName);
                break;
        }
        return $this->parent->getStyleArray(array($key => $array));
    }




После этого всё заработало, ура!!! Сейчас попробуем отправить разработчикам патч, хоть проект и закопали, но кому-то он еще нужен, у кого-то используется и пусть он живет за счет тех, кто это вообще использует.

понедельник, 23 июня 2014 г.

PHPExсel чтение файла Excel

//подключаем главный файл PHPExel, через него инклюдяся все остальные ридеры и редакторы
//но можно подгружать конкретные ридеры для облегчения.
require_once 'PHPExcel.php';

//создается экземпляр класса для чтения xls
$objReader = new PHPExcel_Reader_Excel5();

//или XML XLS
//$objReader = new PHPExcel_Reader_Excel2003XML();

//или XLSX
//$objReader = new PHPExcel_Reader_Excel2007();

//подключаем файлик для чтения $xlsFile - путь до файла xls
 $objPHPExcel = $objReader->load($xlsFile);

//активный лист
$objWorksheet = $objPHPExcel->getActiveSheet();

//получаем количество строк в файле
$highestRow = $objWorksheet->getHighestRow();

//обход строк
for($row=1;($row<=$highestRow);$row++)
    {

        //получение значений ячеек в этой строке

        $val1 = $objWorksheet->getCell("B".$row)->getValue();
        $val2 = $objWorksheet->getCell("C".$row)->getValue();
       

        //если у нас структура, то можем получить уровень строки 
        //для формирования дерева
        $lev=$objWorksheet->getRowDimension($row)->getOutlineLevel();


/*некоторые поставщики делают структуры с вложенностью свыше 8 уровня (0-7), 
это реализуется при помощи отступа (красной строки).*/  
$indent=$objWorksheet->getStyle('B'.$row)->getAlignment()->getIndent();
       

        /*
тут уже ваши специфичные задачи, например импорт  данных в базу*/
       
    }


$objPHPExcel->disconnectWorksheets(); //выгружаем листы после импорта