Запуск phpExcel в Битрикс при ошибке mb_string.func_overload=2
Если в настройках сервера стоит mbstring.func_overload = 2
то phpExcel не запускается, выдавая ошибку. Наблюдал на Битриксе.
Вариант решения - запуск отдельного приложения php cli через shell_exec
.
ExcelConverter
- класс для запуска скрипта array_to_excel.php
. Пример использования:
// $this->sheet - массив по типу [0][0] = 'Значение ячейки' $data = serialize($this->sheet); $converter = new ExcelConverter(); $binData = $converter ->write($data) ->toExcel() ->read();
- services/ExcelConverter.php
<?php class ExcelConverter { public function __construct() { $this->file = tempnam('/tmp', 'xls_'); } public function __destruct() { if(file_exists($this->file)) unlink($this->file); } public function write($binaryData) { $handle = fopen($this->file, 'wb'); if(!is_resource($handle)) throw new Exception("Can not create temp file", 1); if(fwrite($handle, $binaryData) === false) throw new Exception("Can not write temp file", 1); fclose($handle); return $this; } public function toExcel() { $cmd = '/usr/bin/php '.escapeshellcmd($_SERVER["DOCUMENT_ROOT"].'/services/array_to_excel.php '.$this->file); $data = shell_exec($cmd); if(!preg_match('~^FILE SAVED:.*~m', $data)) throw new Exception("Can not convert to Excel", 1); return $this; } public function read() { $handle = fopen($this->file, 'rb'); if(!is_resource($handle)) throw new Exception("Can not open temp file", 1); $binaryData = fread($handle, filesize($this->file)); fclose($handle); return $binaryData; } public function name() { return $this->file; } public function filesize() { return filesize($this->file); } }
- array_to_excel.php
<?php // преобразует массив в Excel файл if(php_sapi_name() !== 'cli') die('Access denied'); // только из CLI class ArrayToExcel { public function __construct() { $dir = dirname(__DIR__); require_once($dir.'/PHPExcel/Classes/PHPExcel/IOFactory.php'); require_once($dir.'/PHPExcel/Classes/PHPExcel/Writer/Excel5.php'); } public function run() { $this->loadData(); $this->fillExcel(); $this->save(); } private $data, $file; private function loadData() { global $argv; $this->file = $argv[1]; if(!file_exists($this->file)) throw new Exception("No file ".$this->file, 1); $handle = fopen($this->file, 'rb'); if(!is_resource($handle)) throw new Exception("Can not open temp file", 1); $binData = fread($handle, filesize($this->file)); fclose($handle); $this->data = unserialize($binData); if($this->data === false || !is_array($this->data)) throw new Exception("Wrong data", 1); } private function fillExcel() { $this->xls = new PHPExcel(); $this->xls->setActiveSheetIndex(0); $sheet = $this->xls->getActiveSheet(); foreach($this->data as $row => $rowData) { foreach($rowData as $col => $data) { $sheet->setCellValueByColumnAndRow($col, $row + 1, (string)$data); // 1-based index } } } private function save() { $objWriter = new PHPExcel_Writer_Excel5($this->xls); $objWriter->save($this->file); echo PHP_EOL.'FILE SAVED: '.$this->file; } } $converter = new ArrayToExcel(); $converter->run();