Cuando se trabaja con grandes volúmenes de datos, la exportación puede saturar la memoria del sistema y causar bloqueos. A continuación, describo dos métodos eefctivos para evitar estos problemas al generar archivos Excel desde PHP.
Ajustes en la Configuración del Servidor
Modiifque los parámetros de configuración del servidor para evitar tiempos de espera excesivos durante la exportación. Estos ajustes son específicos para entornos FastCGI:
fastcgi_connect_timeout 750000;
fastcgi_read_timeout 600000;
fastcgi_send_timeout 600000;
Gestión del Búfer de Salida
Implemente una clase que gestione la liberación periódica del búfer para reducir el consumo de memoria. A continuación, se muestra una clase GeneradorExcel con estas funcionalidades:
<?php
class GeneradorExcel {
private $filasProcesadas = 0;
private $limiteFilasPorFlush;
private $codificacionEntrada = 'UTF-8';
private $codificacionSalida = 'ISO-8859-1';
public function __construct($limite = 1000) {
$this->limiteFilasPorFlush = $limite;
}
public function iniciarExportacion($nombreArchivo, $encabezados) {
$this->enviarCabecerasDescarga($nombreArchivo);
$this->renderizarEncabezados($encabezados);
}
private function enviarCabecerasDescarga($archivo) {
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment; filename="' . $archivo . '.xls"');
header('Pragma: no-cache');
header('Expires: 0');
}
private function renderizarEncabezados($titulos) {
echo '<table border="1"><thead><tr>';
foreach ($titulos as $titulo) {
echo '<th>' . htmlspecialchars($titulo) . '</th>';
}
echo '</tr></thead><tbody>';
$this->refrescarBúfer();
}
public function agregarFila($datos) {
$this->filasProcesadas++;
echo '<tr>';
foreach ($datos as $valor) {
echo '<td>' . htmlspecialchars($valor) . '</td>';
}
echo '</tr>';
if ($this->filasProcesadas % $this->limiteFilasPorFlush === 0) {
$this->refrescarBúfer();
}
}
public function finalizarExportacion() {
echo '</tbody></table>';
$this->refrescarBúfer();
}
private function refrescarBúfer() {
ob_flush();
flush();
}
}
?>
Esta clase puede utilizarse para exportar datos de manera controlada, como se demuestra en el siguiente ejemplo para un conjunto de un millón de registros:
<?php
require 'GeneradorExcel.php';
$generador = new GeneradorExcel(2000);
$encabezados = ['ID', 'Nombre', 'Correo Electrónico'];
$generador->iniciarExportacion('usuarios_exportados', $encabezados);
for ($indice = 0; $indice < 1000000; $indice++) {
$registro = [
$indice + 1,
'Usuario_' . $indice,
'usuario' . $indice . '@ejemplo.com'
];
$generador->agregarFila($registro);
}
$generador->finalizarExportacion();
?>
Al usar este método, el búfer de salida se vacía periódicamente, manteniendo estable el uso de memoria. No obstante, para exportaciones masivas, aún es recomendable verificar que la configuración del servidor permita tiempos de ejecución prolongados.