コード例 #1
0
 public function actionGrid2Excel()
 {
     $model = (string) filter_input(INPUT_GET, 'model');
     // $_GET['model'] - Имя модели, которая выгружается
     $commandmethod = (string) filter_input(INPUT_GET, 'commandmethod');
     // $_GET['commandmethod'] - Имя команды (cDBCommand с запросом), который выгружается
     $collist = (string) filter_input(INPUT_GET, 'collist');
     // $_GET['collist'] - Объект Имя атрибута: Строка поиска фильтра
     if ($model === '' && $commandmethod === '') {
         throw new CHttpException(500, 'Proc/Grid2Excel(): не передан параметр model или commandmethod');
     }
     if ($collist === '') {
         throw new CHttpException(500, 'Proc/Grid2Excel(): не передан параметр collist');
     }
     if ($model !== '' && !method_exists($model, 'GetPermissions')) {
         throw new CHttpException(500, 'Не существует метод "GetPermissions" модели "' . $model . '"');
     }
     if ($model !== '' && !$model::model()->GetPermissions('view')) {
         throw new CHttpException(500, 'Нет доступа для чтения модели "' . $model . '"');
     }
     ini_set('max_execution_time', 1000);
     // 1000 seconds
     ini_set('memory_limit', 1073741824);
     // 1Gbyte Max Memory
     /* Загружаем PHPExcel */
     $objPHPExcel = new PHPExcel();
     $collist = json_decode($collist);
     /* Сотрировка атрибутов */
     $sidx = (string) filter_input(INPUT_GET, 'sidx');
     $sord = (string) filter_input(INPUT_GET, 'sord') !== '' ? (string) filter_input(INPUT_GET, 'sord') : 'ASC';
     $c = 0;
     // Для количества колонок
     if ($model !== '') {
         $methodcriteria = (string) filter_input(INPUT_GET, 'criteriamethod');
         // class_exists($model, false) - дает false, непонятно почему
         /*   if (!class_exists($model, false) || !(method_exists($model, 'model') && $model::model() instanceof CActiveRecord))
              throw new CHttpException(500, $model . ' не является классом CActiveRecord'); */
         if ($methodcriteria !== '' && !method_exists($model, $methodcriteria)) {
             throw new CHttpException(500, 'Метод ' . $methodcriteria . ' отсутствует в модели ' . $model);
         }
         $criteria = $methodcriteria === '' ? new CDbCriteria() : $model::model()->{$methodcriteria}();
         // Берем критерий из модели
         if (!$criteria instanceof CDbCriteria) {
             throw new CHttpException(500, $methodcriteria . ' модели ' . $model . ' не возвращает класс CDbCriteria');
         }
         $model = $model::model();
         if ($sidx !== '') {
             $criteria->order = $sidx . ' ' . $sord;
         }
         /* Применяем критерии поиска */
         $criteria->select = [];
         foreach ($collist as $attr => $val) {
             if ($val->value !== '') {
                 Proc::CompareCriteria($attr, $val->value, $criteria);
             }
             $criteria->select[] = $attr;
         }
         /* Границы таблицы */
         $ramka = array('borders' => array('bottom' => array('style' => PHPExcel_Style_Border::BORDER_THIN), 'top' => array('style' => PHPExcel_Style_Border::BORDER_THIN), 'left' => array('style' => PHPExcel_Style_Border::BORDER_THIN), 'right' => array('style' => PHPExcel_Style_Border::BORDER_THIN)));
         /* Жирный шрифт для шапки таблицы */
         $font = array('font' => array('bold' => true), 'alignment' => array('horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER));
         $rows = ARData::Data($model, $criteria)->GetDataObject();
         if (count((array) $rows) > 0) {
             foreach ($rows->values as $i => $row) {
                 foreach ($rows->fields as $col => $attr) {
                     if ($i == 0) {
                         // заполняем шапку таблицы
                         $objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $i + 1, $attr->label);
                         $objPHPExcel->getActiveSheet()->getStyleByColumnAndRow($col, $i + 1)->applyFromArray($ramka);
                         $objPHPExcel->getActiveSheet()->getStyleByColumnAndRow($col, $i + 1)->applyFromArray($font);
                     }
                     $objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $i + 2, $rows->values[$i][$attr->fieldname]);
                     $objPHPExcel->getActiveSheet()->getStyleByColumnAndRow($col, $i + 2)->applyFromArray($ramka);
                 }
             }
         }
         $c = count($rows->fields);
     } else {
         $command = DBCommands::$commandmethod();
         $command->order($sidx . ' ' . $sord);
         /* Применяем критерии поиска */
         foreach ($collist as $attr => $val) {
             if ($val->value !== '') {
                 Proc::CompareCommand($attr, $val->value, $command);
             }
         }
         $item = $command->select;
         if ($item !== '*') {
             $cols_arr = strchr($item, ', ') === false ? [str_replace('`', '', $item)] : explode(', ', str_replace('`', '', $command->Select));
             array_walk($cols_arr, function (&$item, &$key) {
                 $key = strrchr($item, ' ') === false ? $item : substr(strrchr($item, ' '), 1);
                 $item = $item;
             });
         }
         /* Функция, проверяет, есть ли атрибут в объекте $collist */
         $CheckInArray = function ($attr, $key) use($collist) {
             return property_exists($collist, $key);
         };
         /* Фильтруем список атрибутов критерия, и отсеиваем, если атрибута нет в $collist */
         $cols_arr = array_filter($cols_arr, function ($attr) use($collist) {
             $key = strrchr($attr, ' ') === false ? $attr : substr(strrchr($attr, ' '), 1);
             return property_exists($collist, $key);
         });
         $command->select($cols_arr);
         $recs = $command->queryAll();
         $r = 2;
         // Ряд в Excel, с которого заполняются данные, $r = 1 - ряд для названий атрибутов
         foreach ($recs as $i => $row) {
             $c = 0;
             Proc::ApplyDataValuesbyCommand($row, $collist, $objPHPExcel, $r, $c, $command, $i);
             $r++;
         }
     }
     /* Авторазмер колонок Excel */
     foreach (range(0, $c) as $col) {
         $objPHPExcel->getActiveSheet()->getColumnDimensionByColumn($col)->setAutoSize(true);
     }
     /* присваиваем имя файла от имени модели */
     $FileName = $model !== '' && method_exists($model, 'GetLabel') ? $model->GetLabel() : 'Выгрузка';
     // Устанавливаем имя листа
     $objPHPExcel->getActiveSheet()->setTitle($FileName);
     // Выбираем первый лист
     $objPHPExcel->setActiveSheetIndex(0);
     /* Формируем файл Excel */
     $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
     $FileName = DIRECTORY_SEPARATOR === '/' ? $FileName : mb_convert_encoding($FileName, 'Windows-1251', 'UTF-8');
     /* Proc::SaveFileIfExists() - Функция выводит подходящее имя файла, которое еще не существует. mb_convert_encoding() - Изменяем кодировку на кодировку Windows */
     $fileroot = Proc::SaveFileIfExists('files/' . $FileName . '.xlsx');
     /* Сохраняем файл в папку "files" */
     $objWriter->save('files/' . $fileroot);
     /* Возвращаем имя файла Excel */
     if (DIRECTORY_SEPARATOR === '/') {
         echo $fileroot;
     } else {
         echo mb_convert_encoding($fileroot, 'UTF-8', 'Windows-1251');
     }
 }