NivelExportController.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. <?php
  2. namespace App\Http\Controllers;
  3. use Illuminate\Support\Facades\Log;
  4. use Illuminate\Http\Request;
  5. use Illuminate\Support\Facades\DB;
  6. use Illuminate\Support\Facades\Storage;
  7. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  8. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  9. use PhpOffice\PhpSpreadsheet\Style\Fill;
  10. use PhpOffice\PhpSpreadsheet\Style\Border;
  11. use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
  12. class NivelExportController extends Controller
  13. {
  14. public function exportarExcel(Request $request)
  15. {
  16. $tabla = $request->input('tabla');
  17. switch ($tabla) {
  18. case 'niveles':
  19. return $this->generarReporte('niveles', 'NIVELES EDUCATIVOS', ['idNivel', 'nombreNivel', 'estado']);
  20. case 'materias_categorias':
  21. return $this->generarReporte('materias_categorias', 'CATEGORÍAS DE MATERIAS', ['categoria', 'ordenBoleta', 'estado']);
  22. case 'materias':
  23. return $this->generarReporte('materias', 'MATERIAS', ['idMateria','categoria','nombreMateria','idGradoGrupoRelacionado','afectaBoleta','materiaAcademica','mostrarMateria','estado']);
  24. case 'grados':
  25. return $this->generarReporte('vista_grados_niveles', 'GRADOS', ['idGrado', 'nombreGrado', 'nombreNivel']);
  26. case 'grupos':
  27. return $this->generarReporte('grupos', 'GRUPOS', ['idGrupo', 'nombreGrupo','Estado']);
  28. case 'usuarios':
  29. return $this->generarReporte('usuarios', 'USUARIOS', ['idUsuario', 'tipoUsuario', 'primerNombre','apellidoPaterno','grado','estatus']);
  30. case 'tipos_tareas':
  31. return $this->generarReporte('tareas_tipos', 'TIPOS DE TAREAS', ['idTareasTipos', 'nombreTareasTipos', 'envioPlatTareasTipos','estado']);
  32. case 'relacion_Alumno':
  33. return $this->generarReporte('vista_alumnos_padres_grupos', 'Relacion Alumno', ['idUsuario', 'nombreAlumno', 'grado','nombrePadre','nombreGrupo']);
  34. case 'profesor':
  35. return $this->generarReporte('vista_profesores_materias_grupos', 'Relacion Profesores', ['idUsuario', 'nombreProfesor', 'idMateria','gradoGrupo']);
  36. case 'periodos':
  37. return $this->generarReporte('periodos', 'Periodos', ['idPeriodo', 'fechaFinalizacion', 'estatus']);
  38. default:
  39. return response()->json(['error' => 'Tabla no válida'], 400);
  40. }
  41. }
  42. private function aclararColor(string $hexColor, float $factor = 0.7): string
  43. {
  44. $hexColor = ltrim($hexColor, '#');
  45. $r = hexdec(substr($hexColor, 0, 2));
  46. $g = hexdec(substr($hexColor, 2, 2));
  47. $b = hexdec(substr($hexColor, 4, 2));
  48. $r = min(255, (int)($r + (255 - $r) * $factor));
  49. $g = min(255, (int)($g + (255 - $g) * $factor));
  50. $b = min(255, (int)($b + (255 - $b) * $factor));
  51. return sprintf('%02X%02X%02X', $r, $g, $b);
  52. }
  53. private function generarReporte($tabla, $titulo, $headers)
  54. {
  55. $spreadsheet = new Spreadsheet();
  56. $sheet = $spreadsheet->getActiveSheet();
  57. $colorEncabezado = DB::table('personalizar')->value('PERPR_COL_BAR') ?: '4F81BD';
  58. $colorEncabezado = ltrim($colorEncabezado, '#');
  59. // Título
  60. $sheet->mergeCells('A1:P2');
  61. $sheet->setCellValue('A1', "REPORTE DE $titulo");
  62. $sheet->getStyle('A1:P2')->applyFromArray([
  63. 'font' => ['bold' => true, 'size' => 18, 'name' => 'Century', 'color' => ['rgb' => 'FFFFFF']],
  64. 'alignment' => ['horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
  65. 'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER],
  66. 'fill' => ['fillType' => Fill::FILL_SOLID, 'startColor' => ['rgb' => $colorEncabezado]],
  67. 'borders' => ['bottom' => ['borderStyle' => Border::BORDER_THICK, 'color' => ['rgb' => 'FFFFFF']]],
  68. ]);
  69. $sheet->getRowDimension(1)->setRowHeight(70);
  70. // Logo
  71. $logoPathS3 = DB::table('personalizar')->value('PERLOGO');
  72. if ($logoPathS3 && Storage::disk('s3')->exists($logoPathS3)) {
  73. $tempLogoPath = tempnam(sys_get_temp_dir(), 'logo');
  74. file_put_contents($tempLogoPath, Storage::disk('s3')->get($logoPathS3));
  75. $logo = new Drawing();
  76. $logo->setName('Logo');
  77. $logo->setDescription('Logo de la empresa');
  78. $logo->setPath($tempLogoPath);
  79. $logo->setHeight(90);
  80. $logo->setCoordinates('A1');
  81. $logo->setOffsetX(10);
  82. $logo->setOffsetY(5);
  83. $logo->setWorksheet($sheet);
  84. }
  85. // Descripción
  86. $sheet->mergeCells('H3:J3');
  87. $sheet->setCellValue('H3', "Este reporte muestra los datos registrados en la tabla $tabla.");
  88. $sheet->getStyle('H3')->applyFromArray([
  89. 'font' => ['italic' => true, 'size' => 10, 'name' => 'Century', 'color' => ['rgb' => '333333']],
  90. 'alignment' => ['horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
  91. 'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER],
  92. ]);
  93. // Encabezados
  94. $sheet->fromArray($headers, null, 'H4');
  95. $lastCol = chr(72 + count($headers) - 1);
  96. $sheet->getStyle("H4:$lastCol" . '4')->applyFromArray([
  97. 'font' => ['bold' => true, 'color' => ['rgb' => 'FFFFFF'], 'size' => 12, 'name' => 'Century'],
  98. 'fill' => ['fillType' => Fill::FILL_SOLID, 'startColor' => ['rgb' => $colorEncabezado]],
  99. 'alignment' => ['horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
  100. 'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER],
  101. 'borders' => ['allBorders' => ['borderStyle' => Border::BORDER_THIN, 'color' => ['rgb' => 'FFFFFF']]],
  102. ]);
  103. // Datos con paginación
  104. $datos = DB::table($tabla)
  105. ->select($headers)
  106. ->get();
  107. $row = 5;
  108. $colorClaro = $this->aclararColor($colorEncabezado, 0.85);
  109. foreach ($datos as $index => $registro) {
  110. $col = 'H';
  111. foreach ((array)$registro as $value) {
  112. $sheet->setCellValue($col . $row, $value);
  113. $col++;
  114. }
  115. $sheet->getRowDimension($row)->setRowHeight(25);
  116. $fillColor = $index % 2 === 0 ? $colorClaro : 'FFFFFF';
  117. $sheet->getStyle("H$row:$lastCol$row")->applyFromArray([
  118. 'fill' => ['fillType' => Fill::FILL_SOLID, 'startColor' => ['rgb' => $fillColor]],
  119. 'font' => ['name' => 'Calibri', 'size' => 11],
  120. 'borders' => ['allBorders' => ['borderStyle' => Border::BORDER_THIN, 'color' => ['rgb' => 'BFBFBF']]],
  121. ]);
  122. $row++;
  123. }
  124. foreach (range('H', $lastCol) as $col) {
  125. $sheet->getColumnDimension($col)->setAutoSize(true);
  126. }
  127. $sheet->setAutoFilter("H4:$lastCol" . '4');
  128. $writer = new Xlsx($spreadsheet);
  129. $filename = "$titulo.xlsx";
  130. return response()->streamDownload(function () use ($writer) {
  131. $writer->save('php://output');
  132. }, $filename, [
  133. 'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  134. ]);
  135. }
  136. public function exportarAlumnosRegistro()
  137. {
  138. // === Reutilizamos tu lógica para obtener los datos ===
  139. $data = DB::table('usuarios')
  140. ->leftJoin('registroacademico', 'usuarios.idUsuario', '=', 'registroacademico.idAlumno')
  141. ->leftJoin('usuarios as u2', 'u2.idUsuario', '=', 'registroacademico.usuarioRegistro')
  142. ->select(
  143. DB::raw("CONCAT(COALESCE(usuarios.primerNombre, ''), ' ', COALESCE(usuarios.segundoNombre, ''), ' ', COALESCE(usuarios.apellidoPaterno, ''), ' ', COALESCE(usuarios.apellidoMaterno, '')) AS nombreCompleto"),
  144. DB::raw("CONCAT(COALESCE(u2.primerNombre, ''), ' ', COALESCE(u2.segundoNombre, ''), ' ', COALESCE(u2.apellidoPaterno, ''), ' ', COALESCE(u2.apellidoMaterno, '')) AS nombrePadre"),
  145. 'usuarios.idUsuario',
  146. 'registroacademico.*'
  147. )
  148. ->where('usuarios.tipoUsuario', 'AL')
  149. ->get()
  150. ->map(function($item) {
  151. $hasEmptyField = collect($item)->some(fn($v) => $v === null || $v === '');
  152. return [
  153. 'idUsuario' => $item->idUsuario,
  154. 'quienRegistra' => $item->nombrePadre ?: 'No Aplica',
  155. 'ultActualizacion' => $item->lastUpdate ?: 'No Aplica',
  156. 'nombreCompleto' => $item->nombreCompleto,
  157. 'registroAcCompleto' => $hasEmptyField ? 'No' : 'Sí'
  158. ];
  159. });
  160. $dataAd = DB::table('usuarios')
  161. ->select('usuarios.idUsuario','registroadministrativo.*')
  162. ->leftJoin('registroadministrativo', 'usuarios.idUsuario', '=', 'registroadministrativo.idAlumno')
  163. ->where('usuarios.tipoUsuario', 'AL')
  164. ->get()
  165. ->map(function($item) {
  166. $hasEmptyField = collect($item)->some(fn($v) => $v === null || $v === '');
  167. return [
  168. 'idUsuario' => $item->idUsuario,
  169. 'registroAdCompleto' => $hasEmptyField ? 'No' : 'Sí'
  170. ];
  171. });
  172. $completo = $dataAd->map(function($item) use ($data) {
  173. $registro = $data->firstWhere('idUsuario', $item['idUsuario']);
  174. return [
  175. 'idUsuario' => $item['idUsuario'],
  176. 'quienRegistra' => $registro['quienRegistra'],
  177. 'ultActualizacion' => $registro['ultActualizacion'],
  178. 'nombreCompleto' => $registro['nombreCompleto'],
  179. 'registroAcCompleto' => $registro['registroAcCompleto'],
  180. 'registroAdCompleto' => $item['registroAdCompleto']
  181. ];
  182. })->toArray();
  183. // === Ahora formateamos el Excel ===
  184. $spreadsheet = new Spreadsheet();
  185. $sheet = $spreadsheet->getActiveSheet();
  186. $titulo = "REPORTE DE ALUMNOS";
  187. $headers = ['ID', 'Alumno', 'Quién Registró', 'Última Actualización', 'Académico Completo', 'Administrativo Completo'];
  188. // Estilos título
  189. $sheet->mergeCells('A1:F2');
  190. $sheet->setCellValue('A1', $titulo);
  191. $sheet->getStyle('A1:F2')->applyFromArray([
  192. 'font' => ['bold' => true, 'size' => 18, 'name' => 'Century', 'color' => ['rgb' => 'FFFFFF']],
  193. 'alignment' => ['horizontal' => 'center', 'vertical' => 'center'],
  194. 'fill' => ['fillType' => Fill::FILL_SOLID, 'startColor' => ['rgb' => '4F81BD']],
  195. ]);
  196. $sheet->getRowDimension(1)->setRowHeight(50);
  197. // Logo
  198. $logoPathS3 = DB::table('personalizar')->value('PERLOGO');
  199. if ($logoPathS3 && Storage::disk('s3')->exists($logoPathS3)) {
  200. $tempLogoPath = tempnam(sys_get_temp_dir(), 'logo');
  201. file_put_contents($tempLogoPath, Storage::disk('s3')->get($logoPathS3));
  202. $logo = new Drawing();
  203. $logo->setPath($tempLogoPath);
  204. $logo->setHeight(80);
  205. $logo->setCoordinates('A1');
  206. $logo->setWorksheet($sheet);
  207. }
  208. // Encabezados
  209. $sheet->fromArray($headers, null, 'A4');
  210. $sheet->getStyle("A4:F4")->applyFromArray([
  211. 'font' => ['bold' => true, 'color' => ['rgb' => 'FFFFFF'], 'size' => 12],
  212. 'fill' => ['fillType' => Fill::FILL_SOLID, 'startColor' => ['rgb' => '4F81BD']],
  213. 'alignment' => ['horizontal' => 'center'],
  214. 'borders' => ['allBorders' => ['borderStyle' => Border::BORDER_THIN]],
  215. ]);
  216. // Datos
  217. $row = 5;
  218. foreach ($completo as $index => $item) {
  219. $sheet->fromArray([
  220. $item['idUsuario'],
  221. $item['nombreCompleto'],
  222. $item['quienRegistra'],
  223. $item['ultActualizacion'],
  224. $item['registroAcCompleto'],
  225. $item['registroAdCompleto'],
  226. ], null, "A$row");
  227. $fillColor = $index % 2 === 0 ? 'F2F2F2' : 'FFFFFF';
  228. $sheet->getStyle("A$row:F$row")->applyFromArray([
  229. 'fill' => ['fillType' => Fill::FILL_SOLID, 'startColor' => ['rgb' => $fillColor]],
  230. 'font' => ['name' => 'Calibri', 'size' => 11],
  231. 'borders' => ['allBorders' => ['borderStyle' => Border::BORDER_THIN, 'color' => ['rgb' => 'BFBFBF']]],
  232. ]);
  233. $row++;
  234. }
  235. foreach (range('A', 'F') as $col) {
  236. $sheet->getColumnDimension($col)->setAutoSize(true);
  237. }
  238. $sheet->setAutoFilter("A4:F4");
  239. $writer = new Xlsx($spreadsheet);
  240. $filename = "Alumnos_Registro.xlsx";
  241. return response()->streamDownload(function () use ($writer) {
  242. $writer->save('php://output');
  243. }, $filename, [
  244. 'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  245. ]);
  246. }
  247. }