Exportador e Importador CSV

En muchas ocasiones cuando trabajamos con aplicaciones Web programadas a medida que se alimentan de bases de datos no es fácil para los usuarios o clientes actualizar su contenido si no se dispone de una administración exclusiva para ello.

En este artículo vamos a ver o aprender como programar un importador/exportador de la base de datos a un archivo .csv y viceversa con PHP.

Lo vamos a ver mediante un ejemplo en el cual vamos a querer importar o exportar los siguientes campos: id, nombre, apellidos, email y puntos.

Necesitaremos crear una base de datos y dentro una tabla con el nombre de «usuarios» por ejemplo añadiéndole estos campos. Podemos ver una visualización de la tabla en PHPMyAdmin que necesitaremos en este ejemplo:

Una vez tengamos ubicada nuestra tabla en una base de datos podemos empezar a programar la aplicación. En la siguiente imagen vamos a ver como quedará la aplicación visualmente.

Tal y como vemos en la imagen, la aplicación o módulo contiene 3 partes bien diferenciadas. Por un lado, tenemos el importador del archivo .csv el cual espera que se selecciona del PC y tras pulsar en el botón «upload» proceder a realizar la importación a la base de datos.

En segundo lugar mostramos un botón para obtener una exportación de la base de datos al archivo .csv. En este caso, generamos el archivo .csv con los datos deseados.

Y por último, mostramos una tabla con la información de los usuarios que hay actualmente en la base de datos.

Para disponer de este importador/exportador PHP necesitaremos crear un archivo .php donde en el <body> vamos a implantar toda esta estructura HTML. Tendremos un contenedor centro con 3 fieldsets.

En el primer fieldset tendremos el importador:

<fieldset>
    <legend>Importador de usuarios</legend>
    <?php if (!empty($message_import)) echo $message_import; ?>
    <form enctype="multipart/form-data" method="POST" action="index.php">
        <label>Selecciona un archivo .csv </label>
        <input type="file" name="file">
        <input type="submit" value="Upload" name="submitFileUpload">
    </form>
</fieldset>

En el segundo fieldset el exportador:

<fieldset>
    <legend>Exportar de Usuarios</legend>
    <form method="post" action="index.php">
        <input type="submit" value="Export .CSV file" name="submitExport">
        <?php if (!empty($message_export)) echo $message_export; ?>
    </form>
</fieldset>

Y en el tercer fieldset la tabla que muestra la información disponible o almacenda actualmente:

<fieldset>
    <legend>Usuarios registrados</legend>
    <table width="490px" cellpadding="0" cellspacing="5">
        <tr>
            <td>ID</td>
            <td>Nombre</td>
            <td>Apellido</td>
            <td>Email</td>
            <td align="right">Puntos</td>
        </tr>
           <?php
        $result = $conexion->query("SELECT `id_user`, `name`, `lastname`, `email`, `points` FROM `TU_TABLA` ORDER BY points DESC");
        if ($result->num_rows > 0) {
            while ($row_users = $result->fetch_assoc()) {  
                echo '<tr>';
                echo '<td>'.$row_users['id_user'].'</td>';
                echo '<td>'.$row_users['name'].'</td>';
                echo '<td>'.$row_users['lastname'].'</td>';
                echo '<td>'.$row_users['email'].'</td>';
                echo '<td align="right">'.$row_users['points'].'</td>';
                echo '</tr>';
            }
        }       
        ?>        
    </table>
</fieldset>

Ahora, por encima de cualquier etiqueta HTML añadiremos las tags de código PHP «<?php … ?>» y desarrollaremos allí mismo el código que controlará la importación y la exportación.

Lo primero que haremos será conectar con la base de datos utilizando para ello una clase que nos facilita PHP (msqli) que nos servirá también para generar query’s.

$conexion = new mysqli(DB_SERVER, DB_SERVER_USERNAME, DB_SERVER_PASSWORD, DB_DATABASE);

El código que controlará la exportación será el siguiente:

if(isset($_POST['submitExport'])) {

    $fp = fopen("import/users.csv","w");
    $separador = ";";

    $linea = 'id_user'.$separador.'name'.$separador.'lastname'.$separador.'email'.$separador.'points'."\n"; 
    fwrite($fp, $linea);

    $result = $conexion->query("SELECT `id_user`, `name`, `lastname`, `email`, `points` FROM `TU_TABLA` ORDER BY points DESC");
    if ($result->num_rows > 0) {
        while ($row_users = $result->fetch_assoc()) {                
            $linea = $row_users['id_user'].$separador.$row_users['name'].$separador.$row_users['lastname'].$separador.$row_users['email'].$separador.$row_users['points']."\n"; 
            fwrite($fp, $linea);
        }
    }

    $message_export = '<p><a href="import/users.csv"><b>Ver usuarios .csv</b></a></p>';

    fclose($fp);    
}

En este caso, si pulsamos en el botón de exportación procedemos a abrir un archivo en modo escritura el cual vamos escribiendo linea a linea el contenido que tenemos en la tabla de la base de datos y al finalizar mostramos un link para acceder al archivo generado.

Y el código que controla la importación es el siguiente:

if (isset($_POST['submitFileUpload'])) {

    $file_import = 'import/'.$_FILES['file']['name'];

    if ($_FILES["file"]["type"] == "text/comma-separated-values") {
        if (@move_uploaded_file($_FILES['file']['tmp_name'], $file_import)) {
            $fp = fopen($file_import, 'r');
            $contador = 0;
            $users_edited = 0;
            $users_added = 0;
            while (($data = fgetcsv($fp, 9999, ";")) !== FALSE) {
                if ($contador > 0) {
                    if (empty($data[0])) {
                        $insert = "INSERT INTO `users` (`name`, `lastname`, `email`, `points`) 
                        VALUES ('".$data[1]."', '".$data[2]."', '".$data[3]."', ".$data[4].")";
                        $conexion->query($insert);
                        $users_added++;
                    }
                    else {
                        $update = "UPDATE `users` SET `name`='".$data[1]."', `lastname`='".$data[2]."', `email`='".$data[3]."', `points`=".$data[4]." WHERE id_user=".$data[0];
                        $conexion->query($update);
                        $users_edited++;
                    }
                }
                $contador++;
            }
        }
        $message_import = '<p>La importacion se ha realizado con exito!<br/>Se han actualizado '.$users_edited.' registros.<br/>Se han insertar '.$users_added.' usuarios nuevos.</p>';
    }

    else {
        $message_import = '<p>El archivo subido no es correcto!</p>';
    }
}

La importación es algo más compleja pero si se mira con detalle verás que no es nada del otro mundo. En este caso, si se quiere realizar una importación del archivo .csv a la base de datos, obtenemos el archivo que se quiere subir y comprobamos que sea tipo .csv. De este modo, cualquier otro archivo que se intente subir será denegado.

Si se trata de un archivo .csv se procede a subir el archivo al servidor con la función PHP «move_uploaded_file()», lo abrimos y lo recorremos leyendo su contenido con la función especial solo para archivos .csv «fgetcsv()».

Fíjate que dentro del bucle estamos realizando una comprobación importante que representa las 2 formas de importar. Podremos importar para machacar o modificar y para añadir nuevos. Entonces, si queremos añadir nuevos usuarios conviene dejar vacío el primer campo del .csv, la id para que el script lo interprete con nuevo usuario. Los que tengan id y exista en la tabla «TU_TABLA» serán actualizados en la base de datos.

Autor
Escrito por Jose Aguilar - Director ejecutivo y tecnológico en JA Modules. Experto programador PrestaShop y Experto programador WordPress.
Te ha servido? Valora esta entrada!
(14 votos, promedio: 5 de 5)
Comparte en las redes sociales
¿Buscas trabajo de programador?

24 respuestas a “Exportador e Importador CSV”

  1. Ine Alvarado dice:

    Hola, ¿Y cómo sería para importar una base de datos completa?

    • Jose Aguilar dice:

      Hola,

      Para conseguir esto sería necesario leer todas las tablas de la base de datos y ejecutar un proceso similar al explicado en esta entrada por cada tabla.

      Saludos

  2. jose dice:

    Disculpa la pregunta que hare como se puede hacer una validacion de un combobox con un archivo subido que concuerde con la opcion elegida

  3. bf dice:

    hola
    ¿Existe algun script similar pero automatico?

    Es decir que teniendo un archivo en csv en un servidor pueda rellenar cada uno de los input de un formulario html en forma automatica sin tener que estar haciendo una igualdad entre cada input y su respectivo valor en la celda de excel

    La idea es que sea similar a lo que hace agpform.php pero en sentido opuesto…es decir desde excel o csv a un formulario html….ya que son muchos campos…frecuentemente hago formularios con mas de cien inputs por lo cual es muy honeroso en tiempo el estar haciendo modificaciones al formulario para luego volvera crear los vinculos por codigo…

    Actualmente hago la base de datos automaticamente hacia xls… por lo cual esa base de datps ya se hace con agpform

    gracias
    pd: la idea es poder hacer una busqueda por cedula de identidad y/o cnumero correlativo pero para eso necesito cargar los datos al formulario html

    he hecho una exhaustiva busqueda en la red pero no he podido dar con algun script

    o en otro caso?: se podria hacer que el agpform pueda ser para obtener un archivo .csv? y tambien al reves para cargar desde ese csv obtenido al formulario?… el agpform es codigo libre…

    • Jose Aguilar dice:

      HOla buenas tardes,

      NO he tenido la oportunidad de conocer agpform.php pero si es código libre lo puedes investigar para ver como lo hace.

      Posible es pero requiere horas de trabajo. Si necesitas soporte quizás sea una buena idea contactar en blog@jose-aguilar.com para que te propongamos una solución personalizada.

      Saludos

  4. anibal dice:

    hola, estoy probando este script, lo copie exactamente como esta aca, pero me da siempre El archivo subido no es correcto!

    El .csv que estoy intentando subir, lo genere desde excel, y tiene este formato:

    1,jose,ramirez,jose@gmail.com,12
    2,roberto,rojas,roberto@hotmail.com,25
    3,marcelo,alvarez,roberto@hotmail.com,32
    4,ignacio,fernandez,roberto@hotmail.com,45
    5,sebastian,gonzalez,roberto@hotmail.com,21

    no lo puedo hacer funcionar, me podrias indicar si es que hay un error en donde es que esta y como corregirlo? gracias!!!!

    • Jose Aguilar dice:

      HOla, una buena práctica como programador es debugar el código para ver que está sucediendo. Intenta imprimir la variable que contiene el fichero ($_FILES) para ver de que tipo son los archivos que estás subiendo. Ahí te darás cuenta de lo que sucede…

  5. Macarena dice:

    Hola. No me queda muy claro cómo se realiza la importación.
    En mi caso, lo que pretendo realizar es que el archivo .PHP contenga un código el cuál lea los datos de un archivo .CSV, sin necesidad de tener un botón que lo cargue, que se repone en un directorio a cada hora, y éstos datos los actualice o añada en una base de datos.
    ¿Podría ayudarme y decirme si puedo utilizar este código para lo que yo quiero?
    Gracias de antemano.
    Un saludo

    • Jose Aguilar dice:

      Puedes aprovechar la parte que importa pero de eso tendrás que crear una tarea de cron en el servidor para que se ejecute cada hora.

  6. mario rodriguez dice:

    al momento que le doy upload me manda directamente a archivo incorrecto
    me podrias ayudar porfavor en esta parte porke nose ke es lo que ace
    if (isset($_POST[‘submitFileUpload’])) {

    //que hace esta parte.
    $file_import = ‘import’.$_FILES[‘file’][‘name’];

    if ($_FILES[‘file’][‘type’] == ‘text/comma-separated-values’) {
    echo «SI ESTA YEGANDO»;
    if (@move_uploaded_file($_FILES[‘file’][‘tmp_name’], $file_import)) {
    $fp = fopen($file_import, ‘r’);

  7. mauricio dice:

    No se copio todo el código pero el punto es que seguí paso por paso e incluso la información que yo ya tenía anteriormente almacenada en la tabla ya me aparece

  8. mauricio dice:

    te dejo mi código

    Documento sin título

    0) {
    if (empty($data[0])) {
    $insert = «INSERT INTO `prueba` (`name`, `lastname`, `email`, `points`)
    VALUES (‘».$data[1].»‘, ‘».$data[2].»‘, ‘».$data[3].»‘, «.$data[4].»)»;
    $conexion->query($insert);
    $users_added++;
    }
    else {
    $update = «UPDATE `users` SET `name`='».$data[1].»‘, `lastname`='».$data[2].»‘, `email`='».$data[3].»‘, `points`=».$data[4].» WHERE id_user=».$data[0];
    $conexion->query($update);
    $users_edited++;
    }
    }
    $contador++;
    }
    }
    $message_import = ‘La importacion se ha realizado con exito!Se han actualizado ‘.$users_edited.’ registros.Se han insertar ‘.$users_added.’ usuarios nuevos.’;
    }

    else {
    $message_import = ‘El archivo subido no es correcto!’;
    }
    }

    ?>

    Importador de usuarios

    Selecciona un archivo .csv

    Usuarios registrados

    ID
    Nombre
    Apellido
    Email
    Puntos

    query(«SELECT `id_user`, `name`, `lastname`, `email`, `points` FROM `prueba` ORDER BY points DESC»);
    if ($result->num_rows > 0) {
    while ($row_users = $result->fetch_assoc()) {
    echo »;
    echo ».$row_users[‘id_user’].»;
    echo ».$row_users[‘name’].»;
    echo ».$row_users[‘lastname’].»;
    echo ».$row_users[‘email’].»;
    echo ».$row_users[‘points’].»;
    echo »;
    }
    }

    ?>

     
     

  9. mauricio dice:

    que tal,

    oye una pregunta es que a la hora de importar el archivo me sale
    El archivo subido no es correcto!
    y no se porque es, seguí paso a paso sabes porque es esto?

  10. ehpuig dice:

    Hola Jose.

    En primer lugar, muchas gracias por tu articulo, esta muy bien explicado y creo me servirá para un futuro desarrollo, ya que estoy empezando con php.

    Me ha surgido una duda y quiero aprovechar la oportunidad para consultarte lo siguiente:

    Si en el fichero csv a importar existiese una columna llamada «imagen» cuyo contenido fuese, por ejemplo:

    imagen
    —————-
    C:/img/foto1.jpg
    C:/img/foto2.jpg
    C:/img/xxxxx.jpg
    etc…

    ¿Como deberia tratarlo para que dicha imagen se incorporará en la tabla?

    Agradezco la ayuda que me puedas aportar.
    Un saludo

    • Jose Aguilar dice:

      En la tabla deberás guardar C:/img/foto1.jpg o esto –> foto1.jpg

      Para los archivos ya es otra historia. Tendrás que saber el origen de estas fotos y utilizar alguna función para guardarlas donde quieras.

  11. Ary dice:

    Buen dia! Disculpa estoy checando tu codigo y al momento de oprimir el boton Upload me manda inmediatamente el mensaje: «El archivo subido no es correcto!» En esta parte del codigo que no se que significa el valor ‘import/’
    if (isset($_POST[‘submitFileUpload’])) {

    $file_import = ‘import/’.$_FILES[‘file’][‘name’];

    Si me pudieras ayudar te lo agradeceria mucho. Pd. Muy bueno el codigo y la explicacion! 🙂

  12. alver dice:

    como puedo hacer para validar los datos del csv que la columnas concuerden con los datos a gurdar y que sea los tipos de datos correctos.

    • Jose Aguilar dice:

      Tendrás que mirar cada campo antes de guardar en la base de datos.

      Por ejemplo si quieres registrar la edad deberás controlar con php que sea un número:

      //Si el campo no tiene valor o no es un valor entero
      if (!isset($data[1]) || !is_int($data[1])) {
      $error = true;
      }

      Y luego miras si la varibler error = true no realizas la importación. Es una de las formas pero se puede hacer de otras posiblemente más sotisficadas.

  13. Pablo dice:

    Hola Jose

    Estoy editando un Importador con Csv , con Program Orientada a Objetos,
    y usando Php ,javascript , json y framework zend ,tengo que hacer algunos cambios mas.

    He leido , que hay una forma haciendo unso de algun modulo de Zend , Conoceis alguna ejemplo con zend.

    Si alguien se anima en colaborar en el projecto que me escriba.

    saludos y felicidades por el portal

  14. Manu dice:

    HOla Jose!

    Mira tengo una duda con respecto al código que has colgado en lo referente cuando citas: «El código que controlará la exportación será el siguiente:». Si yo por ejemplo, no conecto a ninguna BBDD y lo quiero escribir directamente en un archivo .csv , ¿en qué parte del código lo pongo?, después de recoger los datos del formulario y antes de hacer la comprobación los errores de los campos? Al final? Como si de una función se tratara?
    Perdona si la pregunta es obvia, pero acabode empezar con PHP y no me aclaro mucho.

    Muchas gracias.

    • Jose Aguilar dice:

      El código php de control debe ir por encima del formulario. Fijate que yo en el ejemplo estoy comprobando si se ha pulsado el botón de importar o exportar entonces realizar la escritura en los archivos como es tu caso.

Deja una respuesta

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

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Ver más sobre