Cargar 200 o 1500 datos en una tabla de nuestra base de datos, uno a uno, es una tarea un poco enredosa, si no aburrida, ya que pasamos mucho tiempo para hacerlo, pudiendo hacerlo en 2 o 3 minutos.
Aquí voy a explicar cómo insertar en la tabla de productos los productos que tengo en una hoja de Excel, y aprovechando, también insertaremos las categorías pertenecientes a los productos.
Entonces, el primer paso es preparar nuestro archivo para insertar nuestro Excel con sus datos.
Paso 1: Configuración de SweetAlert y Librerías Necesarias
Para generar una carga masiva, en este caso, de dos hojas Excel (Productos y categorías), procedemos de la siguiente forma:
1. Incluimos los CDN necesarios para la realización de nuestro proyecto, tanto los CSS como los SCRIPTS.
Aquí dejo el ejemplo de los mismos.
La cabecera
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>AdminTienda</title>
<!-- Google Font: Source Sans Pro -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback">
<!-- Font Awesome Icons -->
<link rel="stylesheet" href="plugins/fontawesome-free/css/all.min.css">
<!-- Theme style -->
<link rel="stylesheet" href="dist/css/adminlte.min.css">
</head>
Los scripts
<script src="plugins/jquery/jquery.min.js"></script>
<!-- Bootstrap 4 -->
<script src="plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- AdminLTE App -->
<script src="dist/js/adminlte.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
Paso 2: Instalación de Composer y PhpSpreadsheet
- Descarga e instala en la computadora Composer desde getcomposer.org.
- ¿Cómo instalamos PhpSpreadsheet?
Pues copiamos este comando composer require phpoffice/phpspreadsheet, luego vamos a nuestro proyecto, abrimos la terminal, nos ubicamos en nuestro proyecto y pegamos el trozo de código que hemos copiado anteriormente. Le damos "enter" y esperamos hasta que las dependencias de la librería PhpSpreadsheet se instalen completamente.
Si miramos nuestro proyecto, veremos que tenemos una nueva carpeta con el nombre "Vendor" y los archivos de Composer. Dentro de la carpeta "Vendor" están los archivos necesarios para hacer la carga de nuestros archivos a la base de datos.
...
Paso 3: Estructura del Proyecto
Asegúrate de que tu proyecto tenga la estructura adecuada, con la carpeta "vendor" generada por Composer.
Paso 4: Maquetación HTML
Crea la estructura HTML con un card de Bootstrap, un input de tipo file y un botón para iniciar la carga masiva:
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<h1 class="m-0">carga masiva de productos</h1>
</div><!-- /.col -->
<div class="col-sm-6">
<ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a href="#">Home</a></li>
</ol>
</div><!-- /.col -->
</div><!-- /.row -->
</div><!-- /.container-fluid -->
</div>
<!-- /.content-header -->
<!-- Main content -->
<div class="content">
<div class="container-fluid">
<div class="row">
<div class="col">
<div class="card card-info">
<div class="card-header">
<h3 class="card-title">Selecionar archivo de carga</h3>
<div class="card-tools">
<button type="button" class="btn btn-tool" data-card-widget="collapse">
<i class="fas fa-minus"></i>
</button>
</div> <!-- ./ end card-tools -->
</div> <!-- ./ end card-header -->
<div class="card-body">
<form action="" method="POST" enctype="multipart/form-data" id="form_cargaProductos">
<div class="row">
<div class="col-10">
<input type="file" name="fileProductos" id="fileProductos" class="form-control"
accept=".xls, .xlsx">
</div>
<div class="col-2">
<input type="submit" value="cargar Productos" class="btn btn-primary"
id="btnCargar">
</div>
</div>
<div class="row text-center ">
<div class="col-12">
<img class="mx-auto" src="../img/loading.gif" id="img_carga" alt=""
style="display: none;">
</div>
</div>
</form>
</div> <!-- ./ end card-body -->
</div>
</div>
</div>
</div><!-- /.container-fluid -->
</div>
Hay que recordar que estamos trabajando con un proyecto onde usamos un template, si lo vas a usar en codigo completo solo hay que aprovechar el formulario, que es la parque que va recoger nuestro excel
Paso 5: Script Ajax
Ahora creamos el script Ajax que va a servir para enviar los datos de la hoja al servidor y recibir la respuesta.
Aqui dejo el codigo del script
<script>
$(document).ready(function() {
$('#form_cargaProductos').on('submit', function(e) {
e.preventDefault();
//Verificar que se seleciono un archivo
if ($('#fileProductos').get(0).files.length == 0) {
Swal.fire({
title: 'Error!',
text: 'Debe selecionar un archivo excel',
icon: 'warning',
showConfirmButton: false,
timer: 2500
})
} else {
//Validar que el archivo sea xls o xlsx
var extensiones_permitidas = ['.xls', 'xlsx'];
var input_file_productos = $('#fileProductos');
var exp_reg = new RegExp("([a-zA-Z0-9\s_\\.\-:])+(" + extensiones_permitidas.join('|') +
")$");
if (!exp_reg.test(input_file_productos.val().toLowerCase())) {
Swal.fire({
title: 'Error!',
text: 'Debe selecionar un archivo excel',
icon: 'warning',
showConfirmButton: false,
timer: 2500
})
return false;
}
var datos = new FormData($('#form_cargaProductos')[0]);
$('#btnCargar').prop("disabled", true);
$('#img_carga').attr('style', 'display:block');
$.ajax({
type: "POST",
url: "ajax/producto_cargaMasiva.php",
data: datos,
cache: false,
contentType: false,
processData: false,
dataType: 'json',
success: function(response) {
console.log(response);
if (response['totalCategorias'] > 0 && response['totalProductos'] > 0) {
Swal.fire({
position: 'center',
icon: 'success',
title: 'Se registraram ' + response['totalCategorias'] +
' categorias ' + 'y ' + response[
'totalProductos'] + 'productos correctamente',
showConfirmButton: false,
timer: 2500
})
$('#btnCargar').prop("disabled", false);
$('#img_carga').attr('style', 'display:none');
} else {
Swal.fire({
position: 'center',
icon: 'error',
title: 'Hay un error en el registro de categorias y productos',
showConfirmButton: false,
timer: 2500
})
}
}
});
}
})
})
</script>
Explicacion del script
Este script en jQuery está diseñado para manejar la carga masiva de productos desde un archivo Excel. Aquí está la explicación detallada:
Document Ready:
$(document).ready(function() {
Espera a que el documento HTML esté completamente cargado antes de ejecutar el script.
Evento de Envío del Formulario:
$('#form_cargaProductos').on('submit', function(e) {
Asocia la función a ejecutar cuando se envía el formulario con el id form_cargaProductos. El evento de envío se cancela inicialmente (e.preventDefault()) para controlar la carga a través de Ajax.
Verificación de Archivo Seleccionado:
if ($('#fileProductos').get(0).files.length == 0) {
Verifica si se ha seleccionado un archivo. Si no, muestra un mensaje de advertencia usando la librería SweetAlert (Swal).
Validación de Extensión del Archivo:
var extensiones_permitidas = ['.xls', 'xlsx'];
var input_file_productos = $('#fileProductos');
var exp_reg = new RegExp("([a-zA-Z0-9\s_\\.\-:])+(" + extensiones_permitidas.join('|') + ")$");
if (!exp_reg.test(input_file_productos.val().toLowerCase())) {
Verifica que el archivo seleccionado tenga una extensión permitida (.xls o .xlsx). Muestra un mensaje de advertencia si la extensión no es válida.
Preparación de Datos para Ajax:
var datos = new FormData($('#form_cargaProductos')[0]);
Crea un objeto FormData con los datos del formulario para enviarlos mediante Ajax.
Deshabilitar Botón y Mostrar Indicador de Carga:
$('#btnCargar').prop("disabled", true);
$('#img_carga').attr('style', 'display:block');
Deshabilita el botón de carga y muestra un indicador de carga mientras se procesa la petición Ajax.
Envío de Datos mediante Ajax:
$.ajax({
// configuración de Ajax
});
Realiza una petición Ajax para enviar los datos al servidor.
Manejo de Respuesta del Servidor:
success: function(response) {
Maneja la respuesta del servidor.
Verificación y Mensajes de SweetAlert:
if (response['totalCategorias'] > 0 && response['totalProductos'] > 0) {
Verifica si se registraron categorías y productos correctamente. Muestra un mensaje de éxito si todo está bien.
} else {
Swal.fire({
position: 'center',
icon: 'error',
title: 'Hay un error en el registro de categorías y productos',
showConfirmButton: false,
timer: 2500
})
}
Muestra un mensaje de error si hay algún problema en el registro.
Restaurar Estado del Botón e Indicador de Carga:
$('#btnCargar').prop("disabled", false);
$('#img_carga').attr('style', 'display:none');
Habilita nuevamente el botón de carga y oculta el indicador de carga después de procesar la respuesta del servidor.
Paso 6: Recibimiento de los datos y envío a la base de datos
En el servidor vamos a recibir los datos de las hojas de Excel y enviar esos datos a la tabla o tablas de la base de datos.
<?php
require_once('../../vendor/autoload.php');
require_once('../../conexion.php');
use PhpOffice\PhpSpreadsheet\IOFactory;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Verificar que se ha enviado un archivo
if (!empty($_FILES['fileProductos']['tmp_name'])) {
$nombreArchivo = $_FILES['fileProductos']['tmp_name'];
// Cargar el documento Excel
$documento = IOFactory::load($nombreArchivo);
// Acceder a la hoja de categorías
$hojaCategorias = $documento->getSheet(1);
// Obtener el número de filas en la hoja de categorías
$numeroFilasCategorias = $hojaCategorias->getHighestDataRow();
$categoriasRegistradas = 0;
$hojaProductos = $documento->getSheetByName('Productos');
$numeroFilasProductos = $hojaProductos->getHighestDataRow();
$productosRegistrados = 0;
for ($i = 2; $i <= $numeroFilasCategorias; $i++) {
// Obtener valores de la hoja de categorías
$categoria = $hojaCategorias->getCellByColumnAndRow(1, $i);
$peso = $hojaCategorias->getCellByColumnAndRow(2, $i);
$fechaActualizacion = date("Y-m-d");
if (!empty($categoria)) {
$sql = "INSERT INTO categorias_productos (categoria, peso, fechaActualizacion)
VALUES (:categoria, :peso, :fechaActualizacion)";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':categoria', $categoria);
$stmt->bindParam(':peso', $peso);
$stmt->bindParam(':fechaActualizacion', $fechaActualizacion);
if ($stmt->execute()) {
$categoriasRegistradas = $categoriasRegistradas + 1;
} else {
$categoriasRegistradas = 0;
}
}
}
if ($categoriasRegistradas > 0) {
for ($i = 2; $i <= $numeroFilasProductos; $i++) {
// Obtener valores de la hoja de productos
$codigoBarras = $hojaProductos->getCell("A" . $i);
$categoria = BuscarIdCategoria($hojaProductos->getCell("B" . $i), $pdo);
$producto = $hojaProductos->getCell("C" . $i);
$precioCompra = $hojaProductos->getCell("D" . $i);
$precioVenta = $hojaProductos->getCell("E" . $i);
$beneficio = $hojaProductos->getCell("F" . $i)->getCalculatedValue();
$stock = $hojaProductos->getCell("G" . $i);
$minimoStock = $hojaProductos->getCell("H" . $i);
$ventas = $hojaProductos->getCell("I" . $i);
$fechaActualizacion = date("Y-m-d");
if (!empty($codigoBarras)) {
$sql = "INSERT INTO productos (codigoBarras, categoria, producto, precioCompra, precioVenta, beneficio, stock, minimoStock, ventas, fechaActualizacion)
VALUES (:codigoBarras, :categoria, :producto, :precioCompra, :precioVenta, :beneficio, :stock, :minimoStock, :ventas, :fechaActualizacion)";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':codigoBarras', $codigoBarras);
$stmt->bindParam(':categoria', $categoria);
$stmt->bindParam(':producto', $producto);
$stmt->bindParam(':precioCompra', $precioCompra);
$stmt->bindParam(':precioVenta', $precioVenta);
$stmt->bindParam(':beneficio', $beneficio);
$stmt->bindParam(':stock', $stock);
$stmt->bindParam(':minimoStock', $minimoStock);
$stmt->bindParam(':ventas', $ventas);
$stmt->bindParam(':fechaActualizacion', $fechaActualizacion);
if ($stmt->execute()) {
$productosRegistrados = $productosRegistrados + 1;
} else {
$productosRegistrados = 0;
}
}
}
}
$respuesta['totalCategorias'] = $categoriasRegistradas;
$respuesta['totalProductos'] = $productosRegistrados;
echo json_encode($respuesta);
}
}
function BuscarIdCategoria($categoria, $pdo) {
$sql = "SELECT idCategoria FROM categorias_productos WHERE categoria = :categoria";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':categoria', $categoria);
$stmt->execute();
// Obtener el resultado del fetch
$resultado = $stmt->fetch(PDO::FETCH_ASSOC);
// Retornar el valor de idCategoria o null si no se encuentra
return ($resultado) ? $resultado['idCategoria'] : null;
}
?>
Explicacicon del codigo
1. Carga del Archivo Excel
El código utiliza la biblioteca PhpSpreadsheet para cargar el archivo Excel. Verifica que se haya enviado un archivo y obtiene su nombre temporal.
<?php
require_once('../../vendor/autoload.php');
require_once('../../conexion.php');
use PhpOffice\PhpSpreadsheet\IOFactory;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!empty($_FILES['fileProductos']['tmp_name'])) {
$nombreArchivo = $_FILES['fileProductos']['tmp_name'];
$documento = IOFactory::load($nombreArchivo);
2. Procesamiento de Categorías
Itera sobre la hoja de categorías del Excel, insertando cada categoría en la tabla 'categorias_productos' de la base de datos. La fecha de actualización se establece en el momento de la inserción.
<?php
for ($i = 2; $i <= $numeroFilasCategorias; $i++) {
$categoria = $hojaCategorias->getCellByColumnAndRow(1, $i);
$peso = $hojaCategorias->getCellByColumnAndRow(2, $i);
$fechaActualizacion = date("Y-m-d");
if (!empty($categoria)) {
$sql = "INSERT INTO categorias_productos (categoria, peso, fechaActualizacion)
VALUES (:categoria, :peso, :fechaActualizacion)";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':categoria', $categoria);
$stmt->bindParam(':peso', $peso);
$stmt->bindParam(':fechaActualizacion', $fechaActualizacion);
if ($stmt->execute()) {
$categoriasRegistradas = $categoriasRegistradas + 1;
} else {
$categoriasRegistradas = 0;
}
}
}
? >
3. Procesamiento de Productos
Similar al paso anterior, itera sobre la hoja de productos y realiza la inserción en la tabla 'productos'. Busca el ID de la categoría correspondiente utilizando la función BuscarIdCategoria.
<?php
for ($i = 2; $i <= $numeroFilasProductos; $i++) {
$codigoBarras = $hojaProductos->getCell("A" . $i);
$categoria = BuscarIdCategoria($hojaProductos->getCell("B" . $i), $pdo);
$producto = $hojaProductos->getCell("C" . $i);
$precioCompra = $hojaProductos->getCell("D" . $i);
$precioVenta = $hojaProductos->getCell("E" . $i);
$beneficio = $hojaProductos->getCell("F" . $i)->getCalculatedValue();
$stock = $hojaProductos->getCell("G" . $i);
$minimoStock = $hojaProductos->getCell("H" . $i);
$ventas = $hojaProductos->getCell("I" . $i);
$fechaActualizacion = date("Y-m-d");
if (!empty($codigoBarras)) {
$sql = "INSERT INTO productos (codigoBarras, categoria, producto, precioCompra, precioVenta, beneficio, stock, minimoStock, ventas, fechaActualizacion)
VALUES (:codigoBarras, :categoria, :producto, :precioCompra, :precioVenta, :beneficio, :stock, :minimoStock, :ventas, :fechaActualizacion)";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':codigoBarras', $codigoBarras);
$stmt->bindParam(':categoria', $categoria);
$stmt->bindParam(':producto', $producto);
$stmt->bindParam(':precioCompra', $precioCompra);
$stmt->bindParam(':precioVenta', $precioVenta);
$stmt->bindParam(':beneficio', $beneficio);
$stmt->bindParam(':stock', $stock);
$stmt->bindParam(':minimoStock', $minimoStock);
$stmt->bindParam(':ventas', $ventas);
$stmt->bindParam(':fechaActualizacion', $fechaActualizacion);
if ($stmt->execute()) {
$productosRegistrados = $productosRegistrados + 1;
} else {
$productosRegistrados = 0;
}
}
}
?>
4. Función BuscarIdCategoria
Esta función busca el ID de una categoría en la base de datos a partir de su nombre. Utilizada para relacionar productos con categorías existentes.
<?php
function BuscarIdCategoria($categoria, $pdo) {
$sql = "SELECT idCategoria FROM categorias_productos WHERE categoria = :categoria";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':categoria', $categoria);
$stmt->execute();
$resultado = $stmt->fetch(PDO::FETCH_ASSOC);
return ($resultado) ? $resultado['idCategoria'] : null;
}
?>
5. Respuesta JSON
Finalmente, el código devuelve una respuesta en formato JSON indicando el número total de categorías y productos registrados.
<?php
$respuesta['totalCategorias'] = $categoriasRegistradas;
$respuesta['totalProductos'] = $productosRegistrados;
echo json_encode($respuesta);
?>

0 Comentarios
Si desea contactar comigo, lo puede hacer atravez deste formulario gracias