Tengo una aplicación basada en CI que me está dando un buen dolor de cabeza con la librería PHPExcel, y es que aun que ya la tengo terminada, tengo un importante problema de lentitud, os cuento un poco:
Explicación:
En el apartado de mi problema la aplicación básicamente pide al usuario un archivo XLS, el cual no se puede modificar, es un Excel con fechas, formulas, formatos, validaciones, etc...Pero lo más importante es que tiene varias hojas aparte de la principal con calendarios laborales de varias provincias españolas, esto hace que el libro tenga muchisimas celdas con valores. Yo en mi aplicación sólo necesito los datos de la hoja principal que son muy pocos, pero las demás hojas no se pueden eliminar ya que la primera depende de estas, tampoco se pueden eliminar justo antes de subir (el fichero para los usuarios está bloqueado y con dichas hojas ocultas).
Problema:
La carga del fichero se hace realmente pesada. Como podía ser por varios motivos (formulas, formatos, protección de hoja, datos) fuí eliminando posibilidades hasta dar con el origen del problema, demasiados datos. Si subo el Excel con la hoja principal únicamente (sin las hojas de calendario), manteniendo todo lo demás (formulas, formatos, protecciones, etc) tarda entre 2 y 3 segundos en realizar la subida, muy por debajo de los 30-120 segundos (o más) que tarda con todas las hojas de Excel.
Muestro un trozo del código de lectura por si ayuda y si alguien ve que me falte algún dato, porque creo que la librería tiene que precargar todos los datos del xls mientras lo procesa, independientemente de los datos que necesites.
Código:
$data = array('upload_data' => $this->upload->data()); // $objReader = PHPExcel_IOFactory::createReader('Excel2007'); // Para XLSX $objReader = PHPExcel_IOFactory::createReader('Excel5'); // Para XLS $objPHPExcel = $objReader->setReadDataOnly(true); $fichero = './uploads/'.$data['upload_data']['file_name']; $objPHPExcel = $objReader->load($fichero); $sheetData = $objPHPExcel->getActiveSheet(1)->toArray(null,false,false,false); $data = array(); $cont = 10; if($objPHPExcel->getActiveSheet()->getCell('B2')->getValue() == "Solicitud Permiso Remunerado"){ // SI ES EL TIPO DE FICHERO EXCEL CORRECTO PROCEDE while ($cont <= 19) { if ($objPHPExcel->getActiveSheet()->getCell('E'.$cont) != "") { $data['nombre'] = $objPHPExcel->getActiveSheet()->getCell('B5')->getValue(); $data['nombre'] .= " "; $data['nombre'] .= $objPHPExcel->getActiveSheet()->getCell('E5')->getValue(); $data['tipo_peticion'][$cont] = $objPHPExcel->getActiveSheet()->getCell('A'.$cont)->getValue(); $data['codigo_emp'] = $objPHPExcel->getActiveSheet()->getCell('J5')->getValue(); $data['provincia'] = $objPHPExcel->getActiveSheet()->getCell('F7')->getValue(); $inicio = $objPHPExcel->getActiveSheet()->getCell('E'.$cont)->getValue(); $inicio = PHPExcel_Shared_Date::ExcelToPHP($inicio); // FUNCION PARA PASAR DE FECHA EXCEL A FECHA PHP $data['inicio'][$cont] = date('Y-m-d', $inicio); $fin = $objPHPExcel->getActiveSheet()->getCell('F'.$cont)->getValue(); $fin = PHPExcel_Shared_Date::ExcelToPHP($fin); $data['fin'][$cont] = date('Y-m-d', $fin); $data['dias'][$cont] = $objPHPExcel->getActiveSheet()->getCell('C'.$cont)->getCalculatedValue(); // COMO LA CELDA TIENE FORMULAS SE EXTRAE EL VALOR CALCULADO } $cont++; } $data['mensaje'] = "<div class='alert alert-success'>Tu fichero se ha subido con éxito! <strong>Aún no se han insertado los datos. Por favor, verifica que sean correctos y confirma.</strong></div>"; }