├── .gitignore ├── ExcelDataReader.php ├── ExcelDataWriter.php ├── ExcelTemplateWriter.php ├── PhpExcel.php ├── README.md └── composer.json /.gitignore: -------------------------------------------------------------------------------- 1 | # phpstorm project files 2 | .idea 3 | 4 | # netbeans project files 5 | nbproject 6 | 7 | # zend studio for eclipse project files 8 | .buildpath 9 | .project 10 | .settings 11 | 12 | # windows thumbnail cache 13 | Thumbs.db 14 | 15 | # composer vendor dir 16 | /vendor 17 | 18 | # composer itself is not needed 19 | composer.phar 20 | 21 | # Mac DS_Store Files 22 | .DS_Store 23 | 24 | # phpunit itself is not needed 25 | phpunit.phar 26 | # local phpunit config 27 | /phpunit.xml -------------------------------------------------------------------------------- /ExcelDataReader.php: -------------------------------------------------------------------------------- 1 | data) || !is_array($this->columns)) { 42 | return; 43 | } 44 | 45 | $this->j = 1; 46 | 47 | $this->writeHeaderRow(); 48 | $this->writeDataRows(); 49 | $this->writeFooterRow(); 50 | } 51 | 52 | protected function writeHeaderRow() 53 | { 54 | $i = 0; 55 | foreach ($this->columns as $column) { 56 | if (isset($column['header'])) { 57 | $this->sheet->setCellValueByColumnAndRow($i, $this->j, $column['header']); 58 | } 59 | if (isset($column['headerStyles'])) { 60 | $this->sheet->getStyleByColumnAndRow($i, $this->j)->applyFromArray($column['headerStyles']); 61 | } 62 | if (isset($column['width'])) { 63 | $this->sheet->getColumnDimensionByColumn($i)->setWidth($column['width']); 64 | } 65 | ++$i; 66 | } 67 | ++$this->j; 68 | } 69 | 70 | protected function writeDataRows() 71 | { 72 | foreach ($this->data as $key => $row) { 73 | $i = 0; 74 | if (isset($this->options['rowOptions']) && $this->options['rowOptions'] instanceof \Closure) { 75 | $rowOptions = call_user_func($this->options['rowOptions'], $row, $key); 76 | } 77 | foreach ($this->columns as $column) { 78 | if (isset($rowOptions)) { 79 | $column = ArrayHelper::merge($column, $rowOptions); 80 | } 81 | if (isset($column['cellOptions']) && $column['cellOptions'] instanceof \Closure) { 82 | $column = ArrayHelper::merge($column, call_user_func($column['cellOptions'], $row, $key, $i, $this->j)); 83 | } 84 | $value = null; 85 | if (isset($column['value'])) { 86 | $value = ($column['value'] instanceof \Closure) ? call_user_func($column['value'], $row, $key) : $column['value']; 87 | } elseif (isset($column['attribute']) && isset($row[$column['attribute']])) { 88 | $value = $row[$column['attribute']]; 89 | } 90 | $this->writeCell($value, $i, $this->j, $column); 91 | ++$i; 92 | } 93 | ++$this->j; 94 | } 95 | } 96 | 97 | protected function writeFooterRow() 98 | { 99 | $i = 0; 100 | foreach ($this->columns as $column) { 101 | // footer config 102 | $config = []; 103 | if (isset($column['footerStyles'])) { 104 | $config['styles'] = $column['footerStyles']; 105 | } 106 | if (isset($column['footerType'])) { 107 | $config['type'] = $column['footerType']; 108 | } 109 | if (isset($column['footerLabel'])) { 110 | $config['label'] = $column['footerLabel']; 111 | } 112 | if (isset($column['footerOptions']) && $column['footerOptions'] instanceof \Closure) { 113 | $config = ArrayHelper::merge($config, call_user_func($column['footerOptions'], null, null, $i, $this->j)); 114 | } 115 | $value = null; 116 | if (isset($column['footer'])) { 117 | $value = ($column['footer'] instanceof \Closure) ? call_user_func($column['footer'], null, null) : $column['footer']; 118 | } 119 | $this->writeCell($value, $i, $this->j, $config); 120 | ++$i; 121 | } 122 | ++$this->j; 123 | } 124 | 125 | protected function writeCell($value, $column, $row, $config) 126 | { 127 | // auto type 128 | if (!isset($config['type']) || $config['type'] === null) { 129 | $this->sheet->setCellValueByColumnAndRow($column, $row, $value); 130 | } elseif ($config['type'] === 'date') { 131 | $timestamp = !is_int($value) ? strtotime($value) : $value; 132 | $this->sheet->SetCellValueByColumnAndRow($column, $row, \PHPExcel_Shared_Date::PHPToExcel($timestamp)); 133 | if (!isset($config['styles']['numberformat']['code'])) { 134 | $config['styles']['numberformat']['code'] = $this->defaultDateFormat; 135 | } 136 | } elseif ($config['type'] === 'url') { 137 | if (isset($config['label'])) { 138 | if ($config['label'] instanceof \Closure) { 139 | // NOTE: calculate label on top level 140 | $label = call_user_func($config['label']/*, TODO */); 141 | } else { 142 | $label = $config['label']; 143 | } 144 | } else { 145 | $label = $value; 146 | } 147 | $urlValid = (filter_var($value, FILTER_VALIDATE_URL) !== false); 148 | if (!$urlValid) { 149 | $label = ''; 150 | } 151 | $this->sheet->setCellValueByColumnAndRow($column, $row, $label); 152 | if ($urlValid) { 153 | $this->sheet->getCellByColumnAndRow($column, $row)->getHyperlink()->setUrl($value); 154 | } 155 | } else { 156 | $this->sheet->setCellValueExplicitByColumnAndRow($column, $row, $value, $config['type']); 157 | } 158 | if (isset($config['styles'])) { 159 | $this->sheet->getStyleByColumnAndRow($column, $row)->applyFromArray($config['styles']); 160 | } 161 | } 162 | 163 | /** 164 | * @return int 165 | */ 166 | public function getJ() 167 | { 168 | return $this->j; 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /ExcelTemplateWriter.php: -------------------------------------------------------------------------------- 1 | resolveFormat($filename); 50 | } 51 | $writer = \PHPExcel_IOFactory::createWriter($object, $format); 52 | ob_start(); 53 | $writer->save('php://output'); 54 | $content = ob_get_clean(); 55 | \Yii::$app->response->sendContentAsFile($content, $filename, $this->resolveMime($format)); 56 | \Yii::$app->end(); 57 | } 58 | 59 | /** 60 | * @param $sheet 61 | * @param $config 62 | */ 63 | public function writeSheetData($sheet, $data, $config) 64 | { 65 | $config['sheet'] = &$sheet; 66 | $config['data'] = $data; 67 | $writer = new ExcelDataWriter($config); 68 | $writer->write(); 69 | return $sheet; 70 | } 71 | 72 | public function writeTemplateData(/* TODO */) 73 | { 74 | // TODO: implement 75 | } 76 | 77 | public function readSheetData($sheet, $config) 78 | { 79 | // TODO: implement 80 | } 81 | 82 | /** 83 | * 84 | * @param $format 85 | * @return string 86 | */ 87 | protected function resolveMime($format) 88 | { 89 | $list = [ 90 | 'CSV' => 'text/csv', 91 | 'HTML' => 'text/html', 92 | 'PDF' => 'application/pdf', 93 | 'OpenDocument' => 'application/vnd.oasis.opendocument.spreadsheet', 94 | 'Excel5' => 'application/vnd.ms-excel', 95 | 'Excel2007' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 96 | ]; 97 | return isset($list[$format]) ? $list[$format] : 'application/octet-stream'; 98 | } 99 | 100 | /** 101 | * 102 | * @param $filename 103 | * @return string 104 | */ 105 | protected function resolveFormat($filename) 106 | { 107 | // see IOFactory::createReaderForFile etc. 108 | $list = [ 109 | 'ods' => 'OpenDocument', 110 | 'xls' => 'Excel5', 111 | 'xlsx' => 'Excel2007', 112 | 'csv' => 'CSV', 113 | 'pdf' => 'PDF', 114 | 'html' => 'HTML', 115 | ]; 116 | // TODO: check strtolower 117 | $extension = pathinfo($filename, PATHINFO_EXTENSION); 118 | return isset($list[$extension]) ? $list[$extension] : $this->defaultFormat; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PHPExcel extension for Yii2 2 | ============= 3 | 4 | [![Latest Stable Version](https://poser.pugx.org/alexgx/yii2-phpexcel/v/stable.svg)](https://packagist.org/packages/alexgx/yii2-phpexcel) [![Total Downloads](https://poser.pugx.org/alexgx/yii2-phpexcel/downloads.svg)](https://packagist.org/packages/alexgx/yii2-phpexcel) [![Latest Unstable Version](https://poser.pugx.org/alexgx/yii2-phpexcel/v/unstable.svg)](https://packagist.org/packages/alexgx/yii2-phpexcel) [![License](https://poser.pugx.org/alexgx/yii2-phpexcel/license.svg)](https://packagist.org/packages/alexgx/yii2-phpexcel) 5 | 6 | %short_description% 7 | 8 | Installation 9 | ------------ 10 | The preferred way to install this extension is through [composer](http://getcomposer.org/download/). 11 | 12 | Either run 13 | 14 | ``` 15 | php composer.phar require "alexgx/yii2-phpexcel" "*" 16 | ``` 17 | or add 18 | 19 | ```json 20 | "alexgx/yii2-phpexcel" : "*" 21 | ``` 22 | 23 | to the require section of your application's `composer.json` file. 24 | 25 | Features 26 | --------------- 27 | TDB 28 | 29 | 30 | Usage 31 | ----- 32 | ``` 33 | 34 | use alexgx\phpexcel; 35 | 36 | ``` 37 | TBD 38 | 39 | Further Information 40 | ------------------- 41 | Please, check the [PHPOffice/PHPExcel github repo](https://github.com/PHPOffice/PHPExcel) documentation for further information about its configuration options. 42 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alexgx/yii2-phpexcel", 3 | "description": "PhpExcel component extension for Yii2.", 4 | "keywords": ["yii", "extension", "component", "PhpExcel"], 5 | "type": "yii2-extension", 6 | "license": "BSD-3-Clause", 7 | "authors": [ 8 | { 9 | "name": "Alexander Gubarev", 10 | "email": "gubarev.alex@gmail.com", 11 | "homepage": "http://actionmedia-labs.net" 12 | } 13 | ], 14 | "require": { 15 | "yiisoft/yii2": "*", 16 | "phpoffice/phpexcel": "1.8.1" 17 | }, 18 | "autoload": { 19 | "psr-4": { 20 | "alexgx\\phpexcel\\": "" 21 | } 22 | } 23 | } --------------------------------------------------------------------------------