Problem solved, for those who need or have a similar problem I share the code. Thanks to everyone for commenting and responding.
<?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];
}
?>