Lenguaje PHP

Importar archivo de Excel a MySQL usando PHP

Importar archivo de Excel a MySQL. Backup y restore de bases de datos es lo más importante en el mantenimiento de un software. El backup automático periódico es imprescindible para cualquier proyecto. Si en caso de que, hay un defecto de seguridad desconocido y que afecta a su sistema, entonces su respaldo es el Santo Grial para salvarle.

La exportación de la base de datos a un archivo de copia de seguridad puede utilizarse en el futuro para restaurar el sistema. Por lo tanto, siempre es necesario verificar el archivo de copia de seguridad haciendo una restauración de prueba. En general, el archivo de copia de seguridad estará en formato SQL, Excel o CSV.

Los clientes de la base de datos disponibles en el mercado proporcionan una opción para importar el archivo de copia de seguridad en estos formatos para restaurar los datos. Vamos a crear nuestro propio cliente de base de datos php para importar datos desde un archivo Excel.

Importar archivo de Excel a MySQL usando PHP

Tengo un formulario HTML con una opción de carga de archivos que sólo acepta archivos de Excel. Después de cargar el archivo, he analizado los datos de Excel para insertarlos en una base de datos.

¿Qué recursos se necesitan?

Utilicé PHPSpreadSheet Library para leer el archivo de Excel. La restauración de Excel backup en una base de datos a través de programación nos ahorrará tiempo. Estudiemos cómo implementar un restore rápido importando datos masivos de archivos de Excel.

Si estás buscando exportar prueba mi artículo anterior sobre exportar datos en formato CSV.

Elegir archivo de Excel para importar datos

Este formulario HTML con la opción de carga de archivos se utiliza para elegir el origen de Excel. Al enviar este formulario, el archivo Excel se enviará al PHP para analizar el origen de datos.

Esta opción de carga de archivos sólo permitirá que los archivos de Excel se elijan mediante el atributo Accept.

Este código también contiene la respuesta HTML para mostrar el mensaje devuelto desde PHP. Este mensaje se muestra basándose en el tipo de respuesta enviada desde PHP después de la importación de Excel.

<h2>Import Excel File into MySQL Database using PHP</h2>
    
    <div class="outer-container">
        <form action="" method="post"
            name="frmExcelImport" id="frmExcelImport" enctype="multipart/form-data">
            <div>
                <label>Choose Excel
                    File</label> <input type="file" name="file"
                    id="file" accept=".xls,.xlsx">
                <button type="submit" id="submit" name="import"
                    class="btn-submit">Import</button>
        
            </div>
        
        </form>
        
    </div>
    <div id="response" class="<?php if(!empty($type)) { echo $type . " display-block"; } ?>"><?php if(!empty($message)) { echo $message; } ?></div>
    
         
<?php
    $sqlSelect = "SELECT * FROM tbl_info";
    $result = mysqli_query($conn, $sqlSelect);

if (mysqli_num_rows($result) > 0)
{
?>
        
    <table class='tutorial-table'>
        <thead>
            <tr>
                <th>Name</th>
                <th>Description</th>

            </tr>
        </thead>
<?php
    while ($row = mysqli_fetch_array($result)) {
?>                  
        <tbody>
        <tr>
            <td><?php  echo $row['name']; ?></td>
            <td><?php  echo $row['description']; ?></td>
        </tr>
<?php
    }
?>
        </tbody>
    </table>
<?php 
} 
?>

Código php para importar datos de Excel a MySQL

Descargue e implemente la biblioteca PHPSpreadSheet en su carpeta de proveedores de aplicaciones. Incluya la ruta de la biblioteca para obtener acceso a las funciones de PHPSpreadSheet para leer los datos de Excel en una matriz.

En este código php, he especificado la matriz de tipo de archivo permitido y comprobar el tipo de archivo cargado está en esta matriz. Después de validar el tipo de archivo, el archivo de Excel se carga en un destino y sus datos se analizan mediante las funciones de la biblioteca PHPSpradSheet.

Calcula el número de hojas y ejecuta un bucle para analizar la hoja de datos por hoja. Para cada iteración de la hoja, he creado un bucle anidado para analizar los datos fila por fila. Después de leer los datos de filas no vacías, dirijo la base de datos Insert y muestro la respuesta.

<?php
$conn = mysqli_connect("localhost","root","test","phpsamples");
require_once('vendor/php-excel-reader/excel_reader2.php');
require_once('vendor/SpreadsheetReader.php');

if (isset($_POST["import"]))
{
       
  $allowedFileType = ['application/vnd.ms-excel','text/xls','text/xlsx','application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'];
  
  if(in_array($_FILES["file"]["type"],$allowedFileType)){

        $targetPath = 'uploads/'.$_FILES['file']['name'];
        move_uploaded_file($_FILES['file']['tmp_name'], $targetPath);
        
        $Reader = new SpreadsheetReader($targetPath);
        
        $sheetCount = count($Reader->sheets());
        
        for($i=0;$i<$sheetCount;$i++)
        {
            $Reader->ChangeSheet($i);
            
            foreach ($Reader as $Row)
            {
          
                $name = "";
                if(isset($Row[0])) {
                    $name = mysqli_real_escape_string($conn,$Row[0]);
                }
                
                $description = "";
                if(isset($Row[1])) {
                    $description = mysqli_real_escape_string($conn,$Row[1]);
                }
                
                if (!empty($name) || !empty($description)) {
                    $query = "insert into tbl_info(name,description) values('".$name."','".$description."')";
                    $result = mysqli_query($conn, $query);
                
                    if (! empty($result)) {
                        $type = "success";
                        $message = "Excel Data Imported into the Database";
                    } else {
                        $type = "error";
                        $message = "Problem in Importing Excel Data";
                    }
                }
             }
        
         }
  }
  else
  { 
        $type = "error";
        $message = "Invalid File Type. Upload Excel File.";
  }
}
?>

Salida de importación de php Excel

Esta captura de pantalla muestra la salida mostrando la lista de filas importadas de la base de datos.

Importar archivo de Excel a MySQL usando PHP
Importar archivo de Excel a MySQL usando PHP

Descargar

Nestor Tapia

Bloggero, amante de la programación PHP, innovador y me fascina compartir información. Desde que conocí el entorno informatico y el internet me llamó la atención la programación, Por tal motivo he creado mi blog BAULPHP.COM para compartir mis experiencias con todos ustedes. ¡Gracias por leerme!.

47 comentarios

  1. como importar columnas especificas de Excel: por ejemplo si tengo un Excel de 10 columnas y quiero solo 6 columnas pero en distinto orden para cargar mi tabla. Como se puede hacer???

  2. Hola! Tendrás idea de como empezar la inserción a partir de la segunda fila del archivo y no desde la primera, esto para dejar la primer fila como encabezado de las columnas? Gracias

  3. Muchas gracias por este aporte. Muy útil.
    Lo he probado en local, con xampp, y funciona perfectamente. En cambio, al subirlo al servidor me da el error «Error cargando el conjunto de caracteres utf8» y no entiendo muy bien por qué.
    Antes de subir nada al servidor lo pruebo en local. La base de datos tiene la misma codificación en xampp y en el servidor (utf8_spanish_ci) y en local va bien pero no en el servidor. Sé que windows (local) es mucho más permisivo que linux (servidor). ¿Cómo puedo solucionar este inconveniente?
    Gracias

  4. Lo probe en local y me funciona al pelo, pero al subirlo a un servidor me marca el siguiente error:

    [13-Oct-2022 23:47:52 UTC] PHP Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; OLERead has a deprecated constructor in /admin/vendor/php-excel-reader/excel_reader2.php on line 95
    [13-Oct-2022 23:47:52 UTC] PHP Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; Spreadsheet_Excel_Reader has a deprecated constructor in /admin/vendor/php-excel-reader/excel_reader2.php on line 312

  5. Saludos.

    Excelente aporte, tengo una consulta, deseo agregar un campo «estado» en la tabla y sus valores serán (activo – inactivo), la idea es que cada vez que importe los registros desde Excel los los registros que se encontraban el la tabla queden con estado «inactivo».

    Agradezco su colaboración.

    1. si se puede, mira agregar el campo en la tabla y al momento de agregarlo indicale que el valor por defecto sera «inactivo» y al momento de importar desde el excel todo lo que se insertara se pondra inactivo

  6. Buenas tardes quiero leer 11000 lineas de excel con 10 campos pero me tira un error de tiempo en el php.ini ya lo subi pero sigue tirando como lo podría hacer para que me funcione.

    1. Hola Fernando

      Si lanza error es por el PHP y PHP necesita mas tiempo de ejecucion, abre un ticket con su hosting, algunos suelen limitar los procesos del PHP

      Saludos

  7. Buenas tardes:

    Excelentisimo aporte!!!
    Quisiera saber como puedo evitar subir la primer fila de la hoja, ya que esta corresponde al encabezado del archivo.

    Muchisimas gracias

  8. Buenas Tardes , se puede importar solo columnas especificas del excel, digamos que el archivo origen tenga 30 columnas y solo se requieren cargar las primeras 5, luego la 11, 12, 17 , 20 y 30 .

    Gracias

  9. estimado estoy usando todos los ejemplos que pones en tu web excelente!
    -Tengo problemas a la hora de importar fecha. En vez de ir la fecha se va un valor entero.
    -Tambien tengo un funcion que saca la resta de fechas pero no guarda el resultado sino la funcion de excel (=IF(ISBLANK(Inventario[[#This Row],[FECHA DE COMPRA]]),» «,(YEAR(TODAY())-YEAR(Inventario[[#This Row],[FECHA DE COMPRA]]))))

    1. Hola Carlos

      Para importar excel a MySQL recuerda que se importa los valores de las celdas, te recomendaria que generes un archivo de excel a partir del original sin funciones, es decir un archivo excel plano.

      Si tienes problemas con las fechas te recomiendo que cambies el formato de fechas, es decir:

      04/11/2021 a 2021-11-04

      Esto debes hacer seleccionado el rango de fechas y usando el cuadro de dialogo «formato de celdas» de excel

      Ejemplo formato de celdas

      Saludos

  10. Me sale este error: Warning: is_readable(): open_basedir restriction in effect. File(/tmp/614a8281e97b5/xl/sharedStrings.xml) is not within the allowed path(s): (/home/admin/web/biiot.ml/public_html:/home/admin/tmp) in /home/admin/web/biiot.ml/public_html/exceltomysql/vendor/SpreadsheetReader_XLSX.php on line 238

    Warning: ZipArchive::extractTo(): open_basedir restriction in effect. File(/tmp/614a8281e97b5) is not within the allowed path(s): (/home/admin/web/biiot.ml/public_html:/home/admin/tmp) in /home/admin/web/biiot.ml/public_html/exceltomysql/vendor/SpreadsheetReader_XLSX.php on line 252

    Warning: is_readable(): open_basedir restriction in effect. File(/tmp/614a8281e97b5/xl/worksheets/sheet1.xml) is not within the allowed path(s): (/home/admin/web/biiot.ml/public_html:/home/admin/tmp) in /home/admin/web/biiot.ml/public_html/exceltomysql/vendor/SpreadsheetReader_XLSX.php on line 409

    Warning: is_readable(): open_basedir restriction in effect. File(/tmp/614a8281e97b5/xl/worksheets/sheet1.xml) is not within the allowed path(s): (/home/admin/web/biiot.ml/public_html:/home/admin/tmp) in /home/admin/web/biiot.ml/public_html/exceltomysql/vendor/SpreadsheetReader_XLSX.php on line 409

    Warning: XMLReader::open(): Empty string supplied as input in /home/admin/web/biiot.ml/public_html/exceltomysql/vendor/SpreadsheetReader_XLSX.php on line 959

    Warning: XMLReader::read(): Load Data before trying to read in /home/admin/web/biiot.ml/public_html/exceltomysql/vendor/SpreadsheetReader_XLSX.php on line 995

    Warning: XMLReader::read(): Load Data before trying to read in /home/admin/web/biiot.ml/public_html/exceltomysql/vendor/SpreadsheetReader_XLSX.php on line 995

  11. buen dia, excelente el aporte.. pero depronto alguién pueda ayudar, quiero cargar un archivo completo de excel, verlo primero en la vista y luego poder seleccionar que columnas son las que quiero almacenar en la base datos.. cual seria la mejor solución y mas ágil a esta necesidad

  12. Hola buen día estoy probando tu código pero tengo errores con las «ñ» lo desconoce y no sube los registros a la base de datos. ¿Qué puedo hacer para solucionarlo?

  13. Hola estimado Antes que nada muchas gracias por el Aporte , quería pedir tu ayuda en este caso como podríamos eliminar la primera columna ya que es la de los encabezados.

    Gracias por tu ayuda!

  14. Buenas tardes, saludos desde Coahuila, México, estimado Nestor mi problema es el siguiente:

    Sube excelentemente la información incluso me manda el mensaje de la subida exitosa, pero igualmente me aparecen estos mensajes… que se puede hacer?

    Warning: «continue» targeting switch is equivalent to «break». Did you mean to use «continue 2»? in C:\xampp\htdocs\plantas\vendor\SpreadsheetReader_XLSX.php on line 456

    Warning: «continue» targeting switch is equivalent to «break». Did you mean to use «continue 2»? in C:\xampp\htdocs\plantas\vendor\SpreadsheetReader_XLSX.php on line 581

    Warning: «continue» targeting switch is equivalent to «break». Did you mean to use «continue 2»? in C:\xampp\htdocs\plantas\vendor\SpreadsheetReader_XLSX.php on line 1049

    Warning: «continue» targeting switch is equivalent to «break». Did you mean to use «continue 2»? in C:\xampp\htdocs\plantas\vendor\SpreadsheetReader_XLSX.php on line 1083

    1. También tengo el mismo problema. Anda a esa ruta que está dentro de vendor y anda a ese SpreadsheetReader_XLSX.php

      Si encuentras algo o si ya lo solucionaste podrías decirlo porfas?

      1. Buenos dias, esos son advertencias pero igual el archivo guarda los datos, yo coloque al incio del php esto:
        error_reporting(0);

        para que no muestre esas advertencias.

    2. Lograste solucionar? a mi me sale el mismo error:

      Warning: «continue» targeting switch is equivalent to «break». Did you mean to use «continue 2»? in C:\xampp\htdocs\prueba\vendor\SpreadsheetReader_XLSX.php on line 581

      Warning: «continue» targeting switch is equivalent to «break». Did you mean to use «continue 2»? in C:\xampp\htdocs\prueba\vendor\SpreadsheetReader_XLSX.php on line 1049

      Warning: «continue» targeting switch is equivalent to «break». Did you mean to use «continue 2»? in C:\xampp\htdocs\prueba\vendor\SpreadsheetReader_XLSX.php on line 1083

    3. hola heliut sanchez,
      tuve ese problema, en cada una deesas lineas que te da error debes cambier la instruccion CONTINUE por BREAK.
      SALUDOS

  15. Buenas tardes. Estoy tratando de usar tu código para un proyecto, tengo la siguiente duda:
    Como puedo hacer que el excel al momento de subirlo se metan los datos a dos o mas tablas?

    1. Hola Carlos,

      Para subir el excel a dos tablas puedes usar dos comandos insert into

      Ejemplo:
      $query = «insert into TABLA_A (name,description) values(‘».$name.»‘,'».$description.»‘)»;
      $result = mysqli_query($conn, $query);

      $query2 = «insert into TABLA_B (name,description) values(‘».$name.»‘,'».$description.»‘)»;
      $result = mysqli_query($conn, $query2);

      Espero haber despejado sus dudas, saludos cordiales

  16. Hola buen día, tengo un problema que es el siguiente:

    Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; Spreadsheet_Excel_Reader has a deprecated constructor in C:\xampp\htdocs\Importar\vendor\php-excel-reader\excel_reader2.php on line 312

    pense que podria ser la version de php, pero tengo instalada la version PHP Version 7.2.34, no se cual seria el problema me podrias ayudar,

  17. Parece que no importa gran cantidad de registros. ya alteteré el PHP.INI en el tiempo máximo y la caapcidad de subida, pero sigue dando el mismo error de exceso de tiempo. Es una tabbla con 9454 registros, solo dos campos. Hice la adecuacion en el index. Solo se importan algunos, luego sale el error de exceder el tiempo de ejecución.

  18. Excelente Nestor, excente! Esto puede ser una herramienta sencilla de migración de datos. Si tenemos los datos en Excel, solo hay que hacer el diseño en blanco de la base de datos en MySQL y con esta aplicación, en un santiamen…zassss! Sencillamente. Saludos!

  19. Desde Chile, estimado porque marca error en esta linea
    $allowedFileType = [‘application/vnd.ms-excel’,’text/xls’,’text/xlsx’,’application/vnd.openxmlformats-officedocument.spreadsheetml.sheet’];

    1. Hola Carlos

      Hay varios factores, uno por ejemplo es la version del PHP
      Se recomienda trabajar en una version standar por ejemplo php7.1 – php7.2
      Para que no exista problemas.

      Si estas trabajando en un servidor localhost, se recomienda trabajar con una version intermedia de localhost y que tenga la version php7.1 o php7.2

    1. Hola Christopher
      Una de las soluciones es formatear el archivo de excel en la columna fechas, por ejemplo (2015-10-25) y si observas que tiene ese formato, lo seleccionas nuevamente y le aplicas el formato nuevamente.

      Saludos y disculpa por responder tan tarde.

  20. Buenas tardes nestor como estas, he seguido tus trabajos y son muy interesantes, tengo una pregunta con respecto a la importación de excel a bases de datos.

    si tengo un archivos y subo y todo esta muy bien, pero en caso que vuelva a subir el mismo archivo hay alguna forma que no repita esos datos si no que me diga esos datos ya están en la base de datos, asi solo se actualizarían solo eso, como puedo hacerlo amigo. muchas gracias.

    1. Creo que somos varios con la misma duda, amigo. Por lo general, se trabaja sobre un mismo archivo de Excel que se actualiza constantemente, y este mismo archivo se sube después a la base de datos.
      Nestor, ¿podrías por favor orientarnos un poco?

      1. Hola Alex,

        La Primera solución que se me ocurre en este momento es el siguiente:

        El script funciona de la siguiente manera, se carga un excel y este fichero con todas sus filas ingresan a la base de datos mediante una consulta llamada INSERT INTO.

        Ahora, la idea es comparar los valores con la base de datos mediante una consulta (SELECT * FROM) y luego haciendo uso de una condicional «if else» comparar si el valor existe o no en la tabla.

        Si la condicional es verdadera, es decir si existe en la base de datos, se podría hacer un UPDATE (actualización).
        Caso contrario si el valor es falso, realizar el (INSERT INTO) tradicional que esta en el ejercicio.

        Espero que esta descripción breve les ayude en su desarrollo. Gracias por leerme.

    2. cordial saludo,
      para lograr lo que estas buscando debemos remplazar «insert into tbl_productos» por «replace into tbl_productos».

      esta operación es una combinación entre un insert y un replace, es decir, en caso de que exista un nuevo registro en excel y no en la BD este lo inserta en la BD, en caso de que hayas modificado algún registro en excel ya existente en la bd se elimina y se reemplaza por la nueva información.

      muy importante, para que funcione debes tener definido una clave primaria en la tabla y siempre tenerla presente en excel, tener en cuenta que este es un método destructivo ya que ejecuta 2 acciones. si existe un duplicado en la primary key elimina el registro e inserta la nueva información del registro. puede afectar su BD dependienta si sus claves externas tienen actualizaciones o eliminaciones en cascada.

      en caso de que lo anterior no te funcione o no sea viable (depende te la estructura de su BD), puedes usar un UPSERT Usando INSERT …… ON DUPLICATE KEY UPDATE

  21. Saludos use este codigo pero con conexion a sql server y me funciona muy bien, quisiera mostrar los datos que estoy importando en una tabla antes de registrarlos, me podrias ayudar o darme una idea.

  22. Saludos use este codigo pero con conecion a sql server y me funciona muy bien, quisiera mostrar los datos que estoy importando en una tabla antes de registrarlos, me podrias ayudar o darme una idea.

    1. Saludos Rainiero,

      Puedes desactivar el insert into en la consulta PHP, con esto podrias visualizar todos los registros del excel.
      A continuación, esos resultados puedes anidarlos en un formulario mediante array y con un botón enviarlos a la base de datos.

      Espero heberte ayudado, saludos a la distancia.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Botón volver arriba