phpphpspreadsheet

PhpSpreadsheet put value of a repeated MYSQL record in a previously inserted EXCEL column


I edit the code since I managed to insert the MYSQL records into Excel, and put the data of DESCRIPCION and DIA (if tipoActividad=1) and NOMBRE_SESION and DIA (if tipoActividad=2) in their place (without repeating their entire range, but the problem is that I cannot resolve the issue that it finds a cell with repeated DNI and puts the current record in the next corresponding cell (for example: if previously AE(nombre_sesion) and AF(dia) were filled with a record, when finding the doc_identity corresponding to that row again, it should place it in cell AG(for nombre_sesion) and AH(dia).

First these are the columns where I want to place myself columns Excel

here is the MYSQL table:

CREATE TABLE `detalle_reporte_mensual` (
  `id_detalle_reporte_mensual` int(8) NOT NULL,
  `id_reporte_mensual` int(8) NOT NULL,
  `id_paciente` int(8) NOT NULL,
  `planificacion_intervencion` varchar(1) NOT NULL,
  `tipo_intervencion` varchar(1) NOT NULL,
  `id_grupo_especifico` int(1) NOT NULL,
  `otros_relevantes` varchar(255) DEFAULT NULL,
  `id_regimen` int(1) NOT NULL,
  `id_etapa` int(1) NOT NULL,
  `id_descripciones` int(3) NOT NULL,
  `dia_actividades` int(2) DEFAULT NULL COMMENT '01-30',
  `id_sesiones` int(1) NOT NULL,
  `observaciones` text DEFAULT NULL COMMENT 'TEMAS',
  `cambio_PPI` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

I have made a modification to my PHP code today(04/11/2024) , let's see if anyone can help me out:

<?php
include("conexion.php"); // Asumiendo que tu conexión está configurada aquí
require __DIR__ . "/vendor/autoload.php";
$objCon = new Conexion();

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use Monolog\Level;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\FirePHPHandler;

// Configuración básica para mostrar todos los errores
error_reporting(E_ALL);
ini_set('display_errors', 'On');

//Guardando el tipo_actividad
// $tipoActividad=2;

class Registro
{
    public $interno;
 
    
    public function __construct($data)
    {
        $this->interno = [
            'doc_identidad' => $data['documento_identidad'],
            'datos_adicionales' => [
                'nombre_completo' => $data['apellidos_nombres_interno'],
                'fecha_ingreso' => $data['fecha_ingreso'],
                'fecha_nac' => $data['fecha_nacimiento'],
                'discapacidad' => $data['discapacidad'],
                'planificacion_intervencion' => $data['planificacion_intervencion'],
                'tipo_intervencion' => $data['tipo_intervencion'],
                'grupo_especifico' => $data['grupo_especifico'],
                'otros_relevantes' => $data['otros_relevantes'],
                'regimen' => $data['regimen'],
                'etapa' => $data['etapa'],
                'pabellon' => $data['pabellon'],
                'descripcion' => mb_convert_encoding($data['descripcion'], "UTF-8"),
                'dia' => $data['dia'],
                'nombre_sesion' => mb_convert_encoding($data['nombre_sesion'], "UTF-8"),
                'profesional' => $data['datos_profesional'],
                'observaciones' => $data['observaciones']
                // ... otros datos adicionales

            ]
        ];


    }
}

class GeneradorReporteExcel
{
    private $spreadsheet;
    private $sheet;
    private $logger;

    public function __construct()
    {
        $this->spreadsheet = new Spreadsheet();
        $this->sheet = $this->spreadsheet->getActiveSheet();

        //Logs
        $this->logger = new Logger('my_app');
        $this->logger->pushHandler(new StreamHandler(__DIR__ . '/reportes/debug.log', Level::Debug));
        // $this->logger->info('My logger is now ready');
        $this->logger->pushHandler(new FirePHPHandler());
    }

    private function obtenerValor($registro, $columna, $fila, $tipoActividad)
    {
        switch ($columna) {
            case 'C':
                return $registro->interno['doc_identidad'];
            case 'D':
                return $registro->interno['datos_adicionales']['nombre_completo'];
            case 'E':
                return 'MASCULINO';
            case 'F':
                return $registro->interno['datos_adicionales']['fecha_ingreso'];
            case 'G':
                return $registro->interno['datos_adicionales']['fecha_nac'];
            case 'H':
                // Obtener la celda de fecha de nacimiento (suponiendo que 'G2' es relativa)
                $celdaFechaNacimiento = 'G' . $fila; // Ajusta la fila según tu lógica
                // Construir la fórmula completa
                $formula = "=(NOW()-" . $celdaFechaNacimiento . ")/365-0.5";
                return $formula;
            case 'I':
                return $registro->interno['datos_adicionales']['discapacidad'];
            case 'J':
                //planificacion d ela intervencion
                if ($registro->interno['datos_adicionales']['planificacion_intervencion'] == 1) {
                    $planificacion_intervencion = "PTI_EN_PROCESO";
                }

                if ($registro->interno['datos_adicionales']['planificacion_intervencion'] == 2) {
                    $planificacion_intervencion = "PTI_P";
                }

                if ($registro->interno['datos_adicionales']['planificacion_intervencion'] == 3) {
                    $planificacion_intervencion = "PTI_S";
                }
                if ($registro->interno['datos_adicionales']['planificacion_intervencion'] == 4) {
                    $planificacion_intervencion = "POPE_ANTIGUA";
                }
                return $planificacion_intervencion;
            case 'K':
                //tipo de intervencion
                if ($registro->interno['datos_adicionales']['tipo_intervencion'] == 1) {
                    $tipo_intervencion = "INDUCCION_Y_ADAPTACION_AL_REGIMEN_PENITENCIARIO";
                }
                if ($registro->interno['datos_adicionales']['tipo_intervencion'] == 2) {
                    $tipo_intervencion = "INTERVENCION_GENERAL";
                }
                if ($registro->interno['datos_adicionales']['tipo_intervencion'] == 3) {
                    $tipo_intervencion = "INTERVENCION_ESPECIALIZADA";
                }
                if ($registro->interno['datos_adicionales']['tipo_intervencion'] == 4) {
                    $tipo_intervencion = "PROGRAMACIÓN_SOBRE_NECESIDADES_DE_INTERVENCIÓN_COMPLEMENTARIA";
                }
                return $tipo_intervencion;
            case 'L':
                return $registro->interno['datos_adicionales']['grupo_especifico'];
            case 'M':
                return $registro->interno['datos_adicionales']['otros_relevantes'];
            case 'N':
                return $registro->interno['datos_adicionales']['regimen'];
            case 'O':
                return $registro->interno['datos_adicionales']['etapa'];
            case 'P':
                return $registro->interno['datos_adicionales']['pabellon'];
            case 'Q':
            case 'S':
            case 'U':
            case 'W':
            case 'Y':
            case 'AA':
            case 'AC':
                if ($tipoActividad === 1) {
                    $descripcion=$registro->interno['datos_adicionales']['descripcion']; // O el campo de descripción que corresponda
                } else {
                    $descripcion='';
                }
                return $descripcion;
            case 'R':
            case 'T':
            case 'V':
            case 'X':
            case 'Z':
            case 'AB':
            case 'AD':
                if ($tipoActividad === 1) {
                    $dia=$registro->interno['datos_adicionales']['dia']; // O el campo de descripción que corresponda
                } else {
                    $dia='';
                }
                return $dia;
            case 'AE':
            case 'AG':
            case 'AI':
            case 'AK':
            case 'AM':
                if ($tipoActividad == 2) {
                    // Manejar el caso cuando tipoActividad es 2 (si aplica)
                    $nombre_sesion=$registro->interno['datos_adicionales']['nombre_sesion']; // O el campo de nombre de sesión que corresponda
                } else {
                    $nombre_sesion='';
                }
                return $nombre_sesion;

            case 'AF':
            case 'AH':
            case 'AJ':
            case 'AL':
            case 'AN':
                if ($tipoActividad == 2) {
                    // Manejar el caso cuando tipoActividad no es 1 ni 2
                    $dia=$registro->interno['datos_adicionales']['dia']; // O el campo de nombre de sesión que corresponda
                } else {
                    $dia='';
                }
                return $dia;

            case 'AO':
                return $registro->interno['datos_adicionales']['profesional'];
            case 'AP':
                return $registro->interno['datos_adicionales']['observaciones'];
                // case 'AQ':
                //     return $registro->interno['datos_adicionales']['nombre_completo'];
            default:
                return '';
        }
    }



    private function escribirEnCelda($columna, $fila, $valor)
    {
        // $this->logger->debug("Escribiendo $valor en la celda $columna$fila");
        // $this->sheet->setCellValue($columna . $fila, $valor);

        try {
            // $this->logger->info('My logger is now ready');
            // $this->logger->debug("Escribiendo $valor en la celda $columna$fila");
            $this->sheet->setCellValue($columna . $fila, $valor);
        } catch (\Exception $e) {
            $this->logger->error("Error al escribir en la celda: " . $e->getMessage());
        }
    }

    private function getRangoColumnas($tipoActividad, $esNuevoRegistro)
    {
        if($tipoActividad==1){
        return $esNuevoRegistro ? ['C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'AA', 'AB', 'AC', 'AD','AO','AP'] : ['O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'AA', 'AB', 'AC', 'AD'];
        }else{
            return $esNuevoRegistro ?  ['C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'AE', 'AF', 'AG', 'AH','AI','AJ','AK','AL','AM','AN','AO','AP'] : ['AE', 'AF', 'AG', 'AH','AI','AJ','AK','AL','AM','AN'];
        }
    }

    private function buscarFilaPorDni($dni)
    {
        // Suponiendo que el DNI está en la columna C
        $highestRow = $this->sheet->getHighestRow();
        $this->logger->debug("Cuantas filas hay?: $highestRow");
        for ($row = 2; $row <= $highestRow; $row++) {
            
            if ($this->sheet->getCell('C' . $row)->getValue() === $dni) {
                // $this->logger->debug("Fila del archivo Excel: $this->sheet->getCell('C' . $row)->getValue() == DNI: $dni");
                $tipoActividad = 2; //$this->sheet->getCell('A' . $row)->getValue(); // Suponiendo que el tipo de actividad está en la columna A
                $rangoColumnas = $this->getRangoColumnas($tipoActividad, false);
                return [
                    'fila' => $row,
                    'rangoColumnas' => $rangoColumnas
                ];
            }
            // $this->logger->debug("DNI EXCEL: $this->sheet->getCell('C' . $row)->getValue()  NO ES IGUAL A DNI SQL: $dni");
            
        }
       
        return false;
     
    }

 private function crearNuevaFila($fila, $registro, $rangoColumnas, $tipoActividad,$esNuevoRegistro) {
    $columnaIndex = 0; // Inicializamos el índice de columna

    foreach ($rangoColumnas as $columna) {
        if($tipoActividad=2 && $esNuevoRegistro==true){
            if($columnaIndex==16 || $columnaIndex==17 || $columnaIndex==18 || $columnaIndex==19 || $columnaIndex==20 || $columnaIndex==21 || $columnaIndex==22){
                // $this->logger->debug("columnaIndex: $columnaIndex - Pertenece a la columna: $columna ---> NO SE REGISTRO");
                continue;
            }
        }else{

            $valor = $this->obtenerValor($registro, $columna, $fila, $tipoActividad);
            $this->escribirEnCelda($columna, $fila, $valor);
            // $this->logger->debug("columnaIndex: $columnaIndex - Pertenece a la columna: $columna ---> valor = $valor ");
            $columnaIndex++;
       }
        
      
        
        // $this->logger->debug("columnaIndex: $columnaIndex - Pertenece a la columna: $columna[$columnaIndex] ---> valor = $valor ");
        // Validación adicional: Verificar si el valor es una cadena vacía o null
        // if (!empty($valor)) {
        //     $this->escribirEnCelda($columna, $fila, $valor);
        //     $columnaIndex++; // Incrementamos el índice solo si escribimos un valor
             
        //     // Si es un nuevo registro y ya escribimos los dos primeros valores, salimos del bucle
        // for($columnaIndex=15;$columnaIndex<24;$columnaIndex++) {
        //         continue 2;
        //     }
        //     // $columnaIndex = 23; // Ajustar el índice para la siguiente columna (AG)
        // }
    }
}
 

    private function actualizarFila($fila, $registro,  $rangosAdicionales=true)
    {
        $tipoActividad = 2; //$registro->tipo_actividad;
        $rangoColumnas = $this->getRangoColumnas($tipoActividad, false);

        // Encontrar la primera columna vacía en el rango adicional
        $columnaVacía = null;
        foreach ($rangosAdicionales[$tipoActividad] as $columna) {
            if ($this->sheet->getCell($columna . $fila)->getValue() === null) {
                $columnaVacía = $columna;
                break;
            }
        }

        // Si se encontró una columna vacía, escribir el valor
        if ($columnaVacía) {
            $columnaIndex = array_search($columnaVacía, $rangoColumnas);
            $valor = $registro->datos_adicionales[$columnaIndex]; // $this->obtenerValor($registro, $columna);
            $this->escribirEnCelda($columnaVacía, $fila, $valor);
        }
    }



    public function generarReporte($registros, $rutaArchivo, $formatoArchivo)
    {
        // Cargar el archivo de formato
        $this->spreadsheet = IOFactory::load($formatoArchivo);
        $this->sheet = $this->spreadsheet->getActiveSheet();

        $fila = 2;

        foreach ($registros as $registro) {
            $tipoActividad = 2; //$registro->datos_adicionales['tipo_intervencion'];

            // Determinar si es un nuevo registro o no ---> OK!
            if ($this->buscarFilaPorDni($registro->interno['doc_identidad'])) {
                $rangoColumnas = $this->getRangoColumnas($tipoActividad, false); // Registro existente
            } else {
                $rangoColumnas = $this->getRangoColumnas($tipoActividad, true); // Nuevo registro
            }


            $dni = $registro->interno['doc_identidad'];
            $filaExistente = $this->buscarFilaPorDni($dni);

            if ($filaExistente) {
                // $this->logger->info('My logger is now ready');
                $this->actualizarFila($filaExistente, $registro, $rangoColumnas);
            } else {
                $this->crearNuevaFila($fila, $registro, $rangoColumnas, $tipoActividad,true);
                $fila++;
            }
        }

        // Guardar el archivo Excel
        $writer = IOFactory::createWriter($this->spreadsheet, 'Xlsx');
        $writer->save($rutaArchivo);
        return "Archivo Generado con Exito!";
    }

    // ... (resto de los métodos)
}

// ... (tu código de conexión a la base de datos y consulta SQL)
$id_reporte = 1;
// Consulta SQL
$sql = "SELECT I.doc_identidad AS 'DOCUMENTO_IDENTIDAD',
                            I.ape_nombres AS 'APELLIDOS_NOMBRES_INTERNO',
                            I.fecha_ingreso AS 'FECHA_INGRESO',
                            I.fecha_nacimiento AS 'FECHA_NACIMIENTO',
                            I.discapacidad AS 'discapacidad',

                            DET.planificacion_intervencion AS 'PLANIFICACION_INTERVENCION',
                            DET.tipo_intervencion AS 'TIPO_INTERVENCION',
                            GRUP.nombre_grupo_especifico AS 'GRUPO_ESPECIFICO',
                            DET.otros_relevantes AS 'OTROS_RELEVANTES',
                            REG.nombre_regimen AS 'REGIMEN',
                            ETP.nombre_etapa AS 'ETAPA',
                            I.pab_celda_etapa AS 'PABELLON',
                            DESCRIP.nombre_descripciones AS 'DESCRIPCION',
                            DET.dia_actividades AS 'dia',
                            SES.nombre_sesiones AS 'nombre_sesion',
                            CONCAT(U.ape_paterno,' ',U.ape_materno,' ',U.nombres) AS 'DATOS_PROFESIONAL',
                            DET.observaciones AS 'OBSERVACIONES',
                            DET.cambio_PTIP_PTIS AS 'PTI_P_PTI_S'
                        FROM reportes_mensuales REP
                        INNER JOIN detalle_reporte_mensual DET ON REP.id_reporte_mensual=DET.id_reporte_mensual
                        INNER JOIN grupo_especifico GRUP ON DET.id_grupo_especifico=GRUP.id_grupo_especifico
                        INNER JOIN internos I ON DET.id_interno=I.id_interno
                        INNER JOIN usuarios U ON REP.id_usuario=U.id_usuario
                        INNER JOIN regimen REG ON DET.id_regimen=REG.id_regimen
                        INNER JOIN etapa ETP ON DET.id_etapa=ETP.id_etapa
                        INNER JOIN descripciones DESCRIP ON DET.id_descripciones=DESCRIP.id_descripciones
                        INNER JOIN sessiones SES ON DET.id_sesiones=SES.id_sesiones

                        WHERE REP.id_reporte_mensual=:id_reporte"; // Tu consulta SQL completa

$rsDetalleReporte = $objCon->getConexion()->prepare($sql);
$rsDetalleReporte->bindParam(':id_reporte', $id_reporte, PDO::PARAM_INT);

if ($rsDetalleReporte->execute()) {
    $registros = [];
    while ($row = $rsDetalleReporte->fetch(PDO::FETCH_ASSOC)) {
        $registro = new Registro($row);
        $registros[] = $registro;
        // Imprimir los datos del registro para verificar
        // echo json_encode($registro)."<br>";
    }

    // Verificar si el array $registros está vacío
    if (empty($registros)) {
        echo "No se encontraron registros.";
    } else {
        // Generar el reporte
        $generador = new GeneradorReporteExcel();
        $generador->generarReporte($registros, 'reportes/reporte_actualizado.xlsx', 'reportes/FORMATO_SOCIAL.xlsx');
    }
} else {
    // Manejar errores en la ejecución de la consulta
    echo "Error al ejecutar la consulta: " . $rsDetalleReporte->errorInfo()[2];
}
?>

responses are appreciated!


Solution

  • Problem solved,. For those who may have a similar problem I am sharing the code

        <?php
    include("conexion.php"); // Asumiendo que tu conexión está configurada aquí
    require __DIR__ . "/vendor/autoload.php";
    $objCon = new Conexion();
    
    use PhpOffice\PhpSpreadsheet\Spreadsheet;
    use PhpOffice\PhpSpreadsheet\IOFactory;
    use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
    use Monolog\Level;
    use Monolog\Logger;
    use Monolog\Handler\StreamHandler;
    use Monolog\Handler\FirePHPHandler;
    
    // Configuración básica para mostrar todos los errores
    error_reporting(E_ALL);
    ini_set('display_errors', 'On');
    
    //Guardando el tipo_actividad e id_reporte
    $tipo_Actividad=$_POST['tipo_actividad'];
    $id_reporte = $_POST['id_reporte'];
    
    class Registro
    {
        public $interno;
        
        public function __construct($data)
        {
            $this->interno = [
                'doc_identidad' => $data['documento_identidad'],
                'datos_adicionales' => [
                    'nombre_completo' => $data['apellidos_nombres_interno'],
                    'fecha_ingreso' => $data['fecha_ingreso'],
                    'fecha_nac' => $data['fecha_nacimiento'],
                    'discapacidad' => $data['discapacidad'],
                    'planificacion_intervencion' => $data['planificacion_intervencion'],
                    'tipo_intervencion' => $data['tipo_intervencion'],
                    'grupo_especifico' => $data['grupo_especifico'],
                    'otros_relevantes' => $data['otros_relevantes'],
                    'regimen' => $data['regimen'],
                    'etapa' => $data['etapa'],
                    'pabellon' => $data['pabellon'],
                    'descripcion' => mb_convert_encoding($data['descripcion'], "UTF-8"),
                    'dia' => $data['dia'],
                    'nombre_sesion' => mb_convert_encoding($data['nombre_sesion'], "UTF-8"),
                    'profesional' => $data['datos_profesional'],
                    'observaciones' => $data['observaciones']
                    // ... otros datos adicionales
    
                ]
            ];
            // $this->nombre_completo = $data['apellidos_nombres_interno'];
    
    
    
        }
    }
    
    class GeneradorReporteExcel
    {
        private $spreadsheet;
        private $sheet;
        private $logger;
        
    
        public function __construct()
        {
            $this->spreadsheet = new Spreadsheet();
            $this->sheet = $this->spreadsheet->getActiveSheet();
    
            //Logs
            $this->logger = new Logger('my_app');
            $this->logger->pushHandler(new StreamHandler(__DIR__ . '/reportes/debug.log', Level::Debug));
            // $this->logger->info('My logger is now ready');
            $this->logger->pushHandler(new FirePHPHandler());
        }
    
        private function obtenerValor($registro, $columna, $fila, $tipoActividad)
        {
            switch ($columna) {
                case 'C':
                    return $registro->interno['doc_identidad'];
                case 'D':
                    return $registro->interno['datos_adicionales']['nombre_completo'];
                case 'E':
                    return 'MASCULINO';
                case 'F':
                    return $registro->interno['datos_adicionales']['fecha_ingreso'];
                case 'G':
                    return $registro->interno['datos_adicionales']['fecha_nac'];
                case 'H':
                    // Obtener la celda de fecha de nacimiento (suponiendo que 'G2' es relativa)
                    $celdaFechaNacimiento = 'G' . $fila; // Ajusta la fila según tu lógica
                    // Construir la fórmula completa
                    $formula = "=(NOW()-" . $celdaFechaNacimiento . ")/365-0.5";
                    return $formula;
                case 'I':
                    return $registro->interno['datos_adicionales']['discapacidad'];
                case 'J':
                    //planificacion d ela intervencion
                    if ($registro->interno['datos_adicionales']['planificacion_intervencion'] == 1) {
                        $planificacion_intervencion = "PTI_EN_PROCESO";
                    }
    
                    if ($registro->interno['datos_adicionales']['planificacion_intervencion'] == 2) {
                        $planificacion_intervencion = "PTI_P";
                    }
    
                    if ($registro->interno['datos_adicionales']['planificacion_intervencion'] == 3) {
                        $planificacion_intervencion = "PTI_S";
                    }
                    if ($registro->interno['datos_adicionales']['planificacion_intervencion'] == 4) {
                        $planificacion_intervencion = "POPE_ANTIGUA";
                    }
                    return $planificacion_intervencion;
                case 'K':
                    //tipo de intervencion
                    if ($registro->interno['datos_adicionales']['tipo_intervencion'] == 1) {
                        $tipo_intervencion = "INDUCCION_Y_ADAPTACION_AL_REGIMEN_PENITENCIARIO";
                    }
                    if ($registro->interno['datos_adicionales']['tipo_intervencion'] == 2) {
                        $tipo_intervencion = "INTERVENCION_GENERAL";
                    }
                    if ($registro->interno['datos_adicionales']['tipo_intervencion'] == 3) {
                        $tipo_intervencion = "INTERVENCION_ESPECIALIZADA";
                    }
                    if ($registro->interno['datos_adicionales']['tipo_intervencion'] == 4) {
                        $tipo_intervencion = "PROGRAMACIÓN_SOBRE_NECESIDADES_DE_INTERVENCIÓN_COMPLEMENTARIA";
                    }
                    return $tipo_intervencion;
                case 'L':
                    return $registro->interno['datos_adicionales']['grupo_especifico'];
                case 'M':
                    return $registro->interno['datos_adicionales']['otros_relevantes'];
                case 'N':
                    return $registro->interno['datos_adicionales']['regimen'];
                case 'O':
                    return $registro->interno['datos_adicionales']['etapa'];
                case 'P':
                    return $registro->interno['datos_adicionales']['pabellon'];
                case 'Q':
                case 'S':
                case 'U':
                case 'W':
                case 'Y':
                case 'AA':
                case 'AC':
                    if ($tipoActividad === 1) {
                        $descripcion=$registro->interno['datos_adicionales']['descripcion']; // O el campo de descripción que corresponda
                    } else {
                        $descripcion='';
                    }
                    return $descripcion;
                case 'R':
                case 'T':
                case 'V':
                case 'X':
                case 'Z':
                case 'AB':
                case 'AD':
                    if ($tipoActividad === 1) {
                        $dia=$registro->interno['datos_adicionales']['dia']; // O el campo de descripción que corresponda
                    } else {
                        $dia='';
                    }
                    return $dia;
                case 'AE':
                case 'AG':
                case 'AI':
                case 'AK':
                case 'AM':
                    if ($tipoActividad == 2) {
                        // Manejar el caso cuando tipoActividad es 2 (si aplica)
                        $nombre_sesion=$registro->interno['datos_adicionales']['nombre_sesion']; // O el campo de nombre de sesión que corresponda
                    } else {
                        $nombre_sesion='';
                    }
                    return $nombre_sesion;
    
                case 'AF':
                case 'AH':
                case 'AJ':
                case 'AL':
                case 'AN':
                    if ($tipoActividad == 2) {
                        // Manejar el caso cuando tipoActividad no es 1 ni 2
                        $dia=$registro->interno['datos_adicionales']['dia']; // O el campo de nombre de sesión que corresponda
                    } else {
                        $dia='';
                    }
                    return $dia;
    
                case 'AO':
                    return $registro->interno['datos_adicionales']['profesional'];
                case 'AP':
                    return $registro->interno['datos_adicionales']['observaciones'];
                    // case 'AQ':
                    //     return $registro->interno['datos_adicionales']['nombre_completo'];
                default:
                    return '';
            }
        }
    
    
    
        private function escribirEnCelda($columna, $fila, $valor)
        {
            // $this->logger->debug("Escribiendo $valor en la celda $columna$fila");
            // $this->sheet->setCellValue($columna . $fila, $valor);
    
            try {
                // $this->logger->info('My logger is now ready');
                // $this->logger->debug("Escribiendo $valor en la celda $columna$fila");
                $this->sheet->setCellValue($columna . $fila, $valor);
            } catch (\Exception $e) {
                $this->logger->error("Error al escribir en la celda: " . $e->getMessage());
            }
        }
    
        private function getRangoColumnas($tipoActividad, $esNuevoRegistro)
        {
            if($tipoActividad==1){
            return $esNuevoRegistro ? ['C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'AA', 'AB', 'AC', 'AD'] : ['O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'AA', 'AB', 'AC', 'AD'];
            }else{
                return $esNuevoRegistro ?  ['C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'AE', 'AF', 'AG', 'AH','AI','AJ','AK','AL','AM','AN','AO','AP'] : ['AE', 'AF', 'AG', 'AH','AI','AJ','AK','AL','AM','AN'];
            }
        }
    
        private function buscarFilaPorDni($dni)
        {
            // Suponiendo que el DNI está en la columna C
            $highestRow = $this->sheet->getHighestRow();
            // $this->logger->debug("Cuantas filas hay?: $highestRow");
            for ($row = 2; $row <= $highestRow; $row++) {
                
                if ($this->sheet->getCell('C' . $row)->getValue() == $dni) {
                    // $this->logger->debug("Fila del archivo Excel: $this->sheet->getCell('C' . $row)->getValue() == DNI: $dni");
                    $tipoActividad = 2; //$this->sheet->getCell('A' . $row)->getValue(); // Suponiendo que el tipo de actividad está en la columna A
                    $rangoColumnas = $this->getRangoColumnas($tipoActividad, false);
                    return [
                        'fila' => $row,
                        'rangoColumnas' => $rangoColumnas
                    ];
                }
                // $this->logger->debug("DNI EXCEL: $this->sheet->getCell('C' . $row)->getValue()  NO ES IGUAL A DNI SQL: $dni");
                
            }
           
            return false;
         
        }
    
     private function crearNuevaFila($fila, $registro, $rangoColumnas, $tipoActividad,$esNuevoRegistro) {
        $columnaIndex = 0; // Inicializamos el índice de columna
    
        foreach ($rangoColumnas as $columna) {
            if($tipoActividad=2 && $esNuevoRegistro==true){
                if($columnaIndex==16 || $columnaIndex==17 || $columnaIndex==18 || $columnaIndex==19 || $columnaIndex==20 || $columnaIndex==21 || $columnaIndex==22){
                    // $this->logger->debug("columnaIndex: $columnaIndex - Pertenece a la columna: $columna ---> NO SE REGISTRO");
                    continue;
                }
            }else{
    
           }
            
            $valor = $this->obtenerValor($registro, $columna, $fila, $tipoActividad);
            $this->escribirEnCelda($columna, $fila, $valor);
            // $this->logger->debug("columnaIndex: $columnaIndex - Pertenece a la columna: $columna ---> valor = $valor ");
            $columnaIndex++;
        }
    }
     
    
        private function actualizarFila($fila, $registro,  $rangosAdicionales)
        {
            $tipoActividad = 2; //$registro->tipo_actividad;
    
            // Encontrar la primera columna vacía en el rango adicional
             $columnaVacia = null;
    
        //    $this->logger->debug("Rango: $rangosAdicionales[$tipoActividad]");
             foreach ($rangosAdicionales as $columna) {
    
                 if ($this->sheet->getCell( $columna. $fila)->getValue() === null) {
                     $columnaVacia =  $columna;
                    //  $this->logger->debug("Columna Vacia: $columnaVacia");
                     break;
                 }
              }
    
            // Si se encontró una columna vacía, escribir el valor
             if ($columnaVacia) {
                //  $columnaIndex = array_search($columnaVacia, $rangosAdicionales);
                //  $this->logger->debug("ColumnaIndex: $columnaIndex ");
                $sesion =$registro->interno['datos_adicionales']['nombre_sesion']; // $this->obtenerValor($registro, $columna);
                $this->escribirEnCelda($columnaVacia, $fila, $sesion);
                //aumentando en 1 para el día
                $columnaVacia++;
                $dia=$registro->interno['datos_adicionales']['dia'];
                $this->escribirEnCelda($columnaVacia, $fila, $dia);
             }
        }
    
    
    
        public function generarReporte($registros, $rutaArchivo, $formatoArchivo,$tipoActividad)
        {
            // Cargar el archivo de formato
            $this->spreadsheet = IOFactory::load($formatoArchivo);
            $this->sheet = $this->spreadsheet->getActiveSheet();
    
            $fila = 2;
    
            foreach ($registros as $registro) {
                $tipoActividad = $tipoActividad; //$registro->datos_adicionales['tipo_intervencion'];
    
                // Determinar si es un nuevo registro o no ---> OK!
                if ($this->buscarFilaPorDni($registro->interno['doc_identidad'])) {
                    $rangoColumnas = $this->getRangoColumnas($tipoActividad, false); // Registro existente
                    //hayando la fila repetida
                    // $dni = $registro->interno['doc_identidad'];
                     $resultadoBusqueda=$this->buscarFilaPorDni($registro->interno['doc_identidad'])['fila'];
                        //  $this->logger->debug("FILA REPETIDA: ".$resultadoBusqueda);
                    // if (is_array($resultadoBusqueda)) {
                    //     $filaExistente =  $resultadoBusqueda[0];//$this->buscarFilaPorDni($dni)[0];
                    //     $this->logger->debug("FILA REPETIDA: $filaExistente");
                    // }
                    $this->actualizarFila($resultadoBusqueda, $registro, $rangoColumnas);
                    //  $this->logger->debug("BuscarFilaDNI devuelve estos valores: ".json_encode($this->buscarFilaPorDni($registro->interno['doc_identidad'])));
                } else {
                    $rangoColumnas = $this->getRangoColumnas($tipoActividad, true); // Nuevo registro
                    $this->crearNuevaFila($fila, $registro, $rangoColumnas, $tipoActividad,true);
                    $fila++;
                    // $this->logger->debug("BuscarFilaDNI devuelve estos valores: ".$this->buscarFilaPorDni($registro->interno['doc_identidad']));
                }
            }
    
            // Guardar el archivo Excel
            $writer = IOFactory::createWriter($this->spreadsheet, 'Xlsx');
            $writer->save($rutaArchivo);
        }
    
    }
    
    
    // Consulta SQL
    $sql = "SELECT I.doc_identidad AS 'DOCUMENTO_IDENTIDAD',
                                I.ape_nombres AS 'APELLIDOS_NOMBRES_INTERNO',
                                I.fecha_ingreso AS 'FECHA_INGRESO',
                                I.fecha_nacimiento AS 'FECHA_NACIMIENTO',
                                I.discapacidad AS 'discapacidad',
    
                                DET.planificacion_intervencion AS 'PLANIFICACION_INTERVENCION',
                                DET.tipo_intervencion AS 'TIPO_INTERVENCION',
                                GRUP.nombre_grupo_especifico AS 'GRUPO_ESPECIFICO',
                                DET.otros_relevantes AS 'OTROS_RELEVANTES',
                                REG.nombre_regimen AS 'REGIMEN',
                                ETP.nombre_etapa AS 'ETAPA',
                                I.pab_celda_etapa AS 'PABELLON',
                                DESCRIP.nombre_descripciones AS 'DESCRIPCION',
                                DET.dia_actividades AS 'dia',
                                SES.nombre_sesiones AS 'nombre_sesion',
                                CONCAT(U.ape_paterno,' ',U.ape_materno,' ',U.nombres) AS 'DATOS_PROFESIONAL',
                                DET.observaciones AS 'OBSERVACIONES',
                                DET.cambio_PTIP_PTIS AS 'PTI_P_PTI_S'
                            FROM reportes_mensuales REP
                            INNER JOIN detalle_reporte_mensual DET ON REP.id_reporte_mensual=DET.id_reporte_mensual
                            INNER JOIN grupo_especifico GRUP ON DET.id_grupo_especifico=GRUP.id_grupo_especifico
                            INNER JOIN internos I ON DET.id_interno=I.id_interno
                            INNER JOIN usuarios U ON REP.id_usuario=U.id_usuario
                            INNER JOIN regimen REG ON DET.id_regimen=REG.id_regimen
                            INNER JOIN etapa ETP ON DET.id_etapa=ETP.id_etapa
                            INNER JOIN descripciones DESCRIP ON DET.id_descripciones=DESCRIP.id_descripciones
                            INNER JOIN sessiones SES ON DET.id_sesiones=SES.id_sesiones
    
                            WHERE REP.id_reporte_mensual=:id_reporte"; // Tu consulta SQL completa
    
    $rsDetalleReporte = $objCon->getConexion()->prepare($sql);
    $rsDetalleReporte->bindParam(':id_reporte', $id_reporte, PDO::PARAM_INT);
    
    if ($rsDetalleReporte->execute()) {
        $registros = [];
        while ($row = $rsDetalleReporte->fetch(PDO::FETCH_ASSOC)) {
            $registro = new Registro($row);
            $registros[] = $registro;
    
            // Imprimir los datos del registro para verificar
            // echo json_encode($registro)."<br>";
        }
    
        // Verificar si el array $registros está vacío
        if (empty($registros)) {
            echo "No se encontraron registros.";
        } else {
            // Generar el reporte
            $generador = new GeneradorReporteExcel();
            $generador->generarReporte($registros, 'reportes/reporte_actualizado.xlsx', 'reportes/FORMATO_SOCIAL.xlsx',$tipo_Actividad);
        }
    } else {
        // Manejar errores en la ejecución de la consulta
        echo "Error al ejecutar la consulta: " . $rsDetalleReporte->errorInfo()[2];
    }
    ?>