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.
Hola, ¿Y cómo sería para importar una base de datos completa?
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
Disculpa la pregunta que hare como se puede hacer una validacion de un combobox con un archivo subido que concuerde con la opcion elegida
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…
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
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!!!!
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…
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
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.
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’);
Hola buenas tardes,
Esa parte lo que hace es darle un nombre al fichero que se va a generar.
Saludos
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
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 »;
}
}
?>
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?
debuga en el código haciendo echos observando que extensión te está llegando y después mira si se está cumpliendo la condición para visualizar ese error.
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
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.
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! 🙂
import es el directorio donde se guardará el archvio subido
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.
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.
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
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.
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.