<?php

require_once $ruta_proyecto . 'vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
//use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
//use PhpOffice\PhpSpreadsheet\Writer\Xls;

final class Excel{
    public $archivo;
    public $formato_archivo;
    public $hojas;
    public $filas;
    public $html;
    public $ruta_guardar;
    public $contrasena;
    private $hoja;

    public $hojas_vacias        = true;
    public $con_encabezado      = false;
    public $reemplazar_vacio    = false;


    // Crear Excel
    function Nuevo(){
        $this->archivo = new Spreadsheet();

        if(!empty($this->contrasena)){
            $this->archivo->getSecurity()->setLockWindows(true);
            $this->archivo->getSecurity()->setLockStructure(true);
            $this->archivo->getSecurity()->setWorkbookPassword($this->contrasena);
        }
    }

    // Leer Excel
    function Leer($ruta_archivo){
        $this->archivo = IOFactory::load($ruta_archivo);
        $this->AsignarHoja();
    }

    function TotalHojas(){
        return $this->archivo->getSheetCount();
    }

    function crearHoja($numero = 0, $titulo = ''){
        if($numero > 0)
            $this->archivo->createSheet($numero);

        $this->AsignarHoja($numero);
        $this->hoja->setTitle($titulo);
    }

    function AsignarHoja($numero = 0){
        $this->hoja = $this->archivo->setActiveSheetIndex($numero);
    }

    function SeleccionarHoja($numero = 0){
        $this->hoja = $this->archivo->getSheet($numero);
    }

    function TotalFilas(){
        return $this->hoja->getHighestRow();
    }

    function LetraUltimaColumna(){
        return $this->hoja->getHighestColumn();
    }

    function TotalColumnas(){
        return Coordinate::columnIndexFromString($this->LetraUltimaColumna());
    }

    function valorCelda($columna, $fila){
        return $this->hoja->getCellByColumnAndRow($columna, $fila)->getValue();
    }

    function enviarValorCelda($columna, $fila, $valor){
        $this->hoja->setCellValueByColumnAndRow($columna, $fila, $valor);
    }

    function cargarFilas(){
        $fila = 0;

        foreach($this->filas as $f){
            ++$fila;
            $columna = 0;

            foreach($f as $v){
                ++$columna;
                $this->enviarValorCelda($columna, $fila, "{$v}");
            }
        }

        $this->filas = NULL;
    }

    function cargarHojas(){
        foreach($this->hojas as $n => $h){
            $titulo = (!empty($h->titulo))? $h->titulo : 'Hoja ' . $n;
            $filas  = $h->filas;

            $this->crearHoja($n, $titulo);

            if(count($filas) > 0){
                $this->filas = $h->filas;
                $this->cargarFilas();
            }
        }

        $this->hojas = NULL;
    }

    function GenerarArchivo(){
        $this->Nuevo();

        if(empty($this->html)){
            if(!empty($this->hojas)){
                $this->cargarHojas();
            }elseif(!empty($this->filas)){
                $this->crearHoja(0, 'Hoja 1');
                $this->cargarFilas();
            }

            $this->AsignarHoja(0);
        }else{
            $lector     = IOFactory::createReader('Html');
            $archivo    = date('U') . '.html';

            crearArchivo($archivo, $this->html);
            $this->archivo = $lector->load($archivo);
            unlink($archivo);
            unset($archivo);
        }

        return IOFactory::createWriter($this->archivo, $this->formato_archivo);
    }

    function Descargar(){
        $this->GenerarArchivo()->save('php://output');
    }

    function Guardar(){
        return $this->GenerarArchivo()->save($this->ruta_guardar);
    }

    function HojaEnArreglo($hoja = 0){
        $this->SeleccionarHoja($hoja);

        $arr_filas          = array();
        $reemplazar_vacio   = $this->reemplazar_vacio;
        $total_filas        = $this->TotalFilas();
        $total_columnas     = $this->TotalColumnas();

        if($total_filas > 0 && $total_columnas > 0){
            for($i = 1; $i <= $total_filas; ++$i){
                if($this->con_encabezado || $i > 1){
                    $arr_columna    = array();
                    $fila_vacia     = true;

                    for($j = 1; $j <= $total_columnas; ++$j){
                        $valor = $this->valorCelda($j, $i);
                        $vacio = (empty($valor));

                        if($vacio){
                            if($reemplazar_vacio !== false)
                                $valor = $reemplazar_vacio;
                        }else
                            $fila_vacia = false;

                        $arr_columna[] = $valor;
                    }

                    if(!$fila_vacia && count($arr_columna) > 0)
                        $arr_filas[] = $arr_columna;

                    unset($arr_columna, $fila_vacia);
                }
            }
        }

        unset($hoja, $reemplazar_vacio, $total_filas, $total_columnas);
        return $arr_filas;
    }

    function ArchivoEnArreglo(){
        $arr_hojas      = array();
        $total_hojas    = $this->TotalHojas();

        if($total_hojas > 0){
            for($i = 0; $i < $total_hojas; ++$i){
                $hoja = $this->HojaEnArreglo($i);

                if($this->hojas_vacias || !empty($hoja))
                    $arr_hojas[] = $hoja;
            }
        }

        return $arr_hojas;
    }
}
