Estoy tratando de crear una barra de progreso al cargar archivos e importar datos en la base de datos.
He creado un importador con laravel y ajax con jquery. En este importador estoy leyendo todos los datos de un archivo CSV. Obtengo todas las filas y columnas de este archivo y, mientras lo leo, realizo una consulta de inserción con eloquent. Este es mi código:
$fp = fopen($route, 'r'); // header $head = fgetcsv($fp, 4096, ';', '"'); $header = []; $header[0] = 'nomape'; $header[1] = 'direccion'; $header[2] = 'cp'; $header[3] = 'ciudad'; $header[4] = 'provincia'; $header[5] = 'telefono'; $header[6] = 'movil'; $rows = 0; $cells = 0; // Rows while($column = fgetcsv($fp, 8192, ';', '"')) { // build array to can combine header and this array $columns = []; foreach ($column as $val) { array_push($columns, $this->delete_accent($val)); } $column = array_combine($header, $columns); $result = Listado::insert($column); if($result){ $rows++; } $cells++; } fclose($fp); return 'Importados un total de: ' .$rows. ' de un total de: ' . $cells; Estas operaciones toman tiempo. En la browser console web en network tab , puedo mostrar mi petición http pendiente mientras importo todos mis datos. Mi CSV tiene un registro 69000.
Con este código estoy construyendo mi barra de progreso:
$.ajax({ xhr: function() { var xhr = new window.XMLHttpRequest(); xhr.upload.addEventListener("progress", function(evt) { if (evt.lengthComputable) { var percentComplete = (evt.loaded / evt.total) * 100; // Place upload progress bar visibility code here console.log(percentComplete); } }, false); return xhr; },Pero esto devuelve el 100% del valor en segundos, cuando estas operaciones toman muchos minutos. Mi pregunta es ¿cómo puedo obtener un progreso real para crear mi barra de progreso?
Debe cambiar su enfoque y realizar el tratamiento csv en 2 pasos mientras repite los segundos pasos hasta el final del archivo.
Primer paso Con ajax, haz una carga normal sin procesar los datos. la solicitud debe devolver el identificador del archivo cargado con el recuento de filas.
Segundo paso Con ajax, solicite que se procesen las primeras 100 filas (cambie el valor de 100 a su gusto)
Una vez que responda la solicitud, actualice la barra de progreso (ya que tiene el recuento total de las filas (100/69000 alias 0.1%) y solicite que se procesen las siguientes 100 entradas.
repita esto hasta llegar al recuento de filas. En el último proceso, puede eliminar el archivo.
PD: necesitará alguna forma de limpiar las cargas basura (aquellas cuyo proceso no ha alcanzado el 100%). Puede hacerlo asignando un nombre inteligente al archivo cargado. Por ejemplo, agregue la fecha de carga (más una identificación única) al nombre del archivo y elimine todo lo que tenga más de 24 horas.
Para cargar, puede usar el lado del cliente para notificar el progreso (si está usando ajax).
xhr.upload.addEventListener("progress", function(evt) { if (evt.lengthComputable) { var percentComplete = evt.loaded / evt.total * 100 >>>0; // Do something with download progress console.log("upload" + percentComplete + "%") } }, false);Para la importación y el progreso del procesamiento del servidor, puede usar A. el servidor WebSockets o B. un proveedor de servicios API (como rejax.io) para esto. Luego, cada vez que se realiza un progreso en el servidor, realiza una llamada a la API y los clientes lo recibirán.
// if using PHP for example. Rejax::send($str_channel_name, $str_message);Divulgador adecuado: ejecuto el servicio https://rejax.io