Subir datos desde un archivo .CSV a una BD MySql


No se han topado con este problema? bueno, les cuento mi experiencia.

Subí una BD a un servidor MySQL, creada con scripts (archivos de texto con sintaxis SQL) pero luego me topé con el problema, que los datos (y muchos) que iba a contener una tabla de la BD, me los proporcionarían en un archivo de Excel. Cómo hacerlo? Me valí de la potencia del php, afortunadamente, estaba en un sistema LAMP, así que no resultó complicada la solucion. A continuación detallo los pasos:

  1. Guardar el archivo de datos que está en Excel como archivo separado por comas (.csv)
  2. Colocar ese archivo donde el servidor web tenga acceso.
  3. Crear un archivo PHP que lea el archivo, le coloque sintaxis sql, y así, lo ingrese a la Base de Datos.
  4. Ejecutar la pagina .php
  5. Listo

La idea es tener un archivo «datos.csv» de la forma:

0001, "Juan Perez", Soltero, 25
0002, "María Lopez", Soltera, 23
0003, "Ester Maldonado", Casada, 36
0004, "Julian Solo Prueba" Divorciado, 40

Para luego ir formando líneas con código SQL que luego se ejecuten, es decir, crear líneas del tipo:

Insert into Persona(Codigo, Nombre, EdoCivil, Edad) values(0001, 'Juan Perez', 'Soltero', 25);
Insert into Persona(Codigo, Nombre, EdoCivil, Edad) values(0002, 'María Lopez', 'Soltera', 23);
Insert into Persona(Codigo, Nombre, EdoCivil, Edad) values(0003, 'Ester Maldonado', 'Casada', 36);
Insert into Persona(Codigo, Nombre, EdoCivil, Edad) values(0004, 'Julian Solo Prueba', 'Divorciado', 40);

El gran reto es ir formando dicha cadena de sintaxis SQL, para luego ejecutarla con
$result=mysql_query($cadena, $enlace);

A continuación les dejo el script php:

<?php

/* Código que lee un archivo .csv con datos, para luego insertarse en una base de datos, vía MySQL
*  Gracias a JoG
*  https://gualinx.wordpress.com
*/   

function Conectarse() //Función para conectarse a la BD
{
       if (!($link=mysql_connect("localhost","miusuario","mipassword")))  { //Cambia estos datos
           echo "Error conectando a la base de datos.";
           exit();
       }
        if (!mysql_select_db("mibd",$link)) {
            echo "Error seleccionando la base de datos.";
           exit();
       }
       return $link;
}

$row = 1;
$handle = fopen("datos.csv", "r"); //Coloca el nombre de tu archivo .csv que contiene los datos
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { //Lee toda una linea completa, e ingresa los datos en el array 'data'
    $num = count($data); //Cuenta cuantos campos contiene la linea (el array 'data')
    $row++;
    $cadena = "insert into miTabla(Campo1,Campo2,Campo3,Campo4) values("; //Cambia los valores 'CampoX' por el nombre de tus campos de tu tabla y colócales los necesarios
    for ($c=0; $c < $num; $c++) { //Aquí va colocando los campos en la cadena, si aun no es el último campo, le agrega la coma (,) para separar los datos
        if ($c==($num-1))
              $cadena = $cadena."'".$data[$c] . "'";
        else
              $cadena = $cadena."'".$data[$c] . "',";
    }

    $cadena = $cadena.");"; //Termina de armar la cadena para poder ser ejecutada
    echo $cadena."<br>";  //Muestra la cadena para ejecutarse

     $enlace=Conectarse();
     $result=mysql_query($cadena, $enlace); //Aquí está la clave, se ejecuta con MySQL la cadena del insert formada
     mysql_close($enlace);
}

fclose($handle);

?>
<h2>Se insertaron <?php echo $row ?> Registros en la tabla miTabla</h2>

Hay que tomar muy encuenta varios aspectos:

  • Revisar bien la sintaxis del archivo .csv, ya que si éste contiene apóstrofos (‘) o comillas dobles («) podrían ocasionar problemas.
  • Nombre de la ruta y del nombre del archivo .csv
  • Nombre de la tabla y de los campos
  • Si al ejecutar la página aparece el código SQL, con el mensaje, «Se insertaron X registros en la tabla MiTabla» y te vas a tu BD y no hay nada, intenta lo siguiente:
  • Copia una línea que te devolvió la página (del tipo «insert into MiTabla… «) y pégala en la consola de SQL, ejecútala y allí te darás cuenta del error SQL posible.

Sé que hay mil y un maneras de poder hacerlo, ésta es una de ellas, espero que te sirva, y si es así, te agradecería que compartas acá tu experiencia, así como yo también la compartí con ustedes.

Tags relacionados en Blogalaxia:

Acerca de JoG

About me? mmhh... pss.. me cuesta describirme a mi mismo, aunque. ya pasé como 30 segundos pensando qué escribir... bueno, les puedo decir que soy un chavo guatemalteco, con ganas de aprender más cosas. Cada vez que leo, me doy cuenta que sé menos. Estoy estudiando Ingenieria en Sistemas, me gusta el tema de la tecnología. Soy alguien que le gusta ayudar a los demás. (Partidiario de Software Libre?) mmhh... jaja.. bueno, sí me gusta, aunque sé que en este mundo uuuff! me falta mucho por aprender, y no me considero un linuxero a morir, que se sabe todas los comandos en consola y todo eso, pero sí utilizo Linux. Tengo Ubuntu 7.04. Que mas? ... mmhh.... ah, soy alguien que quiere ver una GuateLinda cambiada, donde podamos nuevamente caminar por las calles tranquilamente, sin miedo a la violencia. Creo que en pocos años, veré realidad ese sueño.
Esta entrada fue publicada en General, php, Tecnología y etiquetada , , . Guarda el enlace permanente.

88 respuestas a Subir datos desde un archivo .CSV a una BD MySql

  1. fernanda gonzalez dijo:

    hola probe el cod y no funciona al abrir la tabla no aparece nada de la informacion que supuestamente subio y ademas muestra todo el codigo en la pagina no se que pasa y ya revise igual muchas gracias

  2. JoG dijo:

    Revisa si tienes correcto:
    – Nombre del servidor (en mi caso, ‘localhost’)
    – Nombre de la Base de Datos, el usuario y el password
    – Nombre de la ruta y del archivo .csv
    – Nombre de la tabla, y de los campos.

    Aunque creo que puede ser porque la sintaxis de entrada no es la correcta, para ello revisa bien los nombres de los campos donde los estas insertando. Para una prueba, inserta desde consola un solo registro, (algo asi como
    insert into Persona(nombre, edad, nacionalidad) values ('Juanito Perez', 15, 'guatemalteco');

    y alli veras los posibles errores que te pueda dar en consola mysql. Arregla la cadena a modo que pueda ser una cadena valida, y luego arregla la cadena del PHP.
    Revisa bien tus datos de entrada, ya que toma en cuenta que podrian traer apostrofos (‘) y eso podria causar problema
    Suerte.

  3. lore dijo:

    lo que sucede es que el script tira lineas del tipo:
    insert into Persona(nombre, edad, nacionalidad) values (‘Juanito Perez; 15 ; guatemalteco’);
    no separa con , sino que lo hace con ; y no coloca los apostrofes (‘) entre las comas, por lo que dice q el numero de campos a insertar no coincide con los que hay en la tabla
    ademas el for que aparece ahi no sirve porque tira todos los campos en una sola linea, para arreglarlo basta esta linea:

    $data[$c]=str_replace(‘;’,’\’,\»,$data[$c]);

    antes del for

  4. marie dijo:

    $data[$c]=str_replace(’;’,’\’,\”,$data[$c]); no entiendo que cadena esta comparando y tratando de separar el asunto es q da error no entiendo que hace por favor
    podrias explicarme para tratar de arreglarlo Lore por favor

  5. jose tito dijo:

    Ok Amigo, si me funciono,….. gracias por tus aportes……..

  6. rusbel dijo:

    mi problema es que tengo barios txt a cada minuto se genera un txt como capturo y subo ami base de datos mysql

  7. JoG dijo:

    @rusbel:
    podrías explicarlo mejor?
    Los txt que hablas son archivos que contienen datos para guardar en una tabla?
    Si es así… Cómo son generados esos archivos? talvez al momento de generarse, se puede guardar a la BD. No se si estoy mal.

  8. Agustin dijo:

    A mi no me funciono, pero modificando un poco el codigo logre que imprima en pantalla los datos para ingresar en el SQL de phpmyadmin, asi que realmente fue muy util ya que traje una base de datos de excel de 10000 productos aprox… me sacaste de un lio! gracias!

  9. JoG dijo:

    @Agustin: Que bueno que lograste hacer tu trabajo y me alegra haber podido ayudarte.
    Otra cosa… nos podrias compartir qué problema tuviste y como lo solucionaste? Gracias

  10. john dijo:

    agustin puedes compartir el codigo para ver estoy en las mismas te lo agradesco saludos

  11. Funciona perfecto mil y mil gracias era justo lo que necesitaba.

  12. BSAA dijo:

    A mi funcionó, pero sólo me inserta 600 registro de 5,153, me envía el siguiente error:
    Fatal error: Maximum execution time of 30 seconds exceeded in C:\wamp\www\Jurado\sube_archivos.php on line 32.

    Saben como solucionar esto?

  13. JoG dijo:

    Hola BSAA, tu problema puede ser por varias razones:
    -Como indiqué antes, revisa muy bien tus datos de entrada que no contengan algun caracter que de problema y cause un bucle infinito, como el apóstrofo (‘), o comilla, ya que éste crearía confusión en la cadena que se crea. Intenta evitarlo, y si no se puede, pues intenta «parsear» la cadena para ir buscando ese apóstrofo y reemplazarlo.

    – Si ya te diste cuenta que todos tus datos están bien, Puede ser que realmente sea problema del límite configurado en PHP. Busca el archivo «php.ini» y edita la parte: max_execution_time = 30 y auméntale a 120. Guarda, y reinicia tu Webserver
    – Si eso no da resultado, puedes también cambiar un parámetro de Apache: puedes agregar (o buscar) la linea php_value max_execution_time 60 en el archivo .httaccess Guarda, y reinicia el servidor

    Prueba y cuéntanos si te funciona

  14. Alan dijo:

    Alguien podria mandar el código completo con las correciones
    porq me sale un error en
    $data[$c]=str_replace(’;’,’\’,\”,$data[$c]);
    gracias

  15. JoG dijo:

    Hola Alan, el script así como está funciona, pero si tienes el mismo problema que lore, que el script te da resultados del tipo: insert into Persona(nombre, edad, nacionalidad) values (’Juanito Perez; 15 ; guatemalteco’);
    la linea correcta que hay que agregar sería:
    $data[$c]=str_replace(";","’, ”, $data[$c]);

  16. Alan dijo:

    Hola JOG entonces quedaria asi??? porque me da este error:

    Parse error: syntax error, unexpected ‘;’ in …\prueba.php on line 29

    $row = 1;
    $handle = fopen(«datos.csv», «r»);
    while (($data = fgetcsv($handle, 1000, «,»)) !== FALSE) {
    $num = count($data);
    $row++;
    $cadena = «insert into miTabla(Campo1,Campo2,Campo3,Campo4) values(«;
    $data[$c]=str_replace(”;”,”’, ”, $data[$c]);//ESTA ES LA LINEA 29
    for ($c=0; $c < $num; $c++) {
    if ($c==($num-1))
    $cadena = $cadena.»‘».$data[$c] . «‘»;
    else
    $cadena = $cadena.»‘».$data[$c] . «‘,»;
    }

    $cadena = $cadena.»);»;
    echo $cadena.»»;

    $enlace=Conectarse();
    $result=mysql_query($cadena, $enlace);
    mysql_close($enlace);
    }

    fclose($handle);

  17. Malcom dijo:

    Gracias amigo por este codigo me sirvio de mucho

  18. cristian dijo:

    Hola.. gracias por el código a mi me sirvio demasiado, pero tengo problemas, te cuento. En el PC donde estoy trabajando la carga masiva de datos mediante el archivo .csv funciona perfecto tanto localmente como en el servidor q esta en otro PC todo esto creando el archivo .csv aca en mi estacion de trabajo. El problema surge cuando en otros PC’s q estan en la red intento hacer la carga masiva creando en ellos los archivos CSV no lo inserta, pero si yo los creo en mi estacion de trabajo y los comparto en red mediante carpeta compartida, funciona…

    Pero.. al intentar abrir el archivo se visualiza todo en una sola celda… q problemas puede ser?

    Espero me puedas ayudar… saludos

  19. Novato dijo:

    Muchas gracias por el codigo, pero tengo un problemilla estoy usando este codigo creo que es el correcto
    <?php
    function Conectarse()
    {
    if (!($link=mysql_connect(«localhost:8888″,»xxx»,»xxx»))) {
    echo «Error conectando a la base de datos.»;
    exit();
    }
    if (!mysql_select_db(«ColegioMedicos»,$link)) {
    echo «Error seleccionando la base de datos.»;
    exit();
    }
    return $link;
    }

    $row = 1;
    $handle = fopen(«colegiados.csv», «r»);
    while (($data = fgetcsv($handle, 1000, «,»)) !== FALSE) {
    $num = count($data);
    $row++;
    $cadena = «insert into colegiados(codigo,apellido1,apellido2,nombre,calle) values(«;
    $data[$c]=str_replace(”;”,”’, ”, $data[$c]);
    for ($c=0; $c < $num; $c++) {
    if ($c==($num-1))
    $cadena = $cadena.»‘».$data[$c] . «‘»;
    else
    $cadena = $cadena.»‘».$data[$c] . «‘,»;
    }

    $cadena = $cadena.»);»;
    echo $cadena.»»;

    $enlace=Conectarse();
    $result=mysql_query($cadena, $enlace);
    mysql_close($enlace);
    }

    fclose($handle);

    ?>
    Se insertaron Registros en la tabla miTabla

    Y el fichero csv tiene esta forma
    20000;xxx;yyyyy;zzzzz;uuuuuuuuu
    0000000;dasdasd;dasdas;dsada;asdsd

    y tras su ejecución pues no hace nada de nada y no se que puede ser le he dado ya muchas vueltas.

    Muchas gracias.

  20. Camilo dijo:

    Muchas gracias por tu código, funciona sin problemas solo es cambiar datos de usuario y de la base datos.

    Muchas gracias.

  21. Bonifacio dijo:

    tengo un problema, cuando ejecuto el script me pone esto en la web

    INSERT INTO tabla VALUES (‘993837′,’demo’,’demo’,’demo’,’demo’,’demo’,»2009-04-03»);

    Fatal error: Function name must be a string in /home/supervisor/www/temp/subircsv.php on line 22

    Veo que es el doble apostofre del ultimo campo, pero no logro quitarlo. he modificado el script asi:

    $cadena=$cadena.$data[$c];
    else
    $cadena=$cadena.$data[$c].»,»;

    Esto porque en mi CSV tengo los datos en apostrofes.

    en la linea 22 tengo:

    $result=mysql_query($cadena,$enlace);

    Espero me puedan ayudar

  22. JoG dijo:

    @Bonifacio: Podrías colocar una lína de ejemplo de tu archivo CSV? porque si dices que tienes datos con apóstrofes habrá que manipular esas valores antes de insertarlas a la cadena SQL.

  23. DMN dijo:

    Gracias por el script funciono de maravilla.

  24. Ferahe dijo:

    Me funciono muy bien, solo que tengo un problema, ¿con un mismo archivo puedo meter datos a dos tablas diferentes de la mima base?

  25. JoG dijo:

    Claro que sí puedes, lo único que tienes que hacer es armar correctamente la cadena con la sintaxis sql la cual insertará los datos en la tabla2. De manera que quede algo similar a:
    $cadena2 = «insert into miTabla2(Campo1,Campo2,Campo3) values(valor1, valor2,valor3)»;

    y luego despues del primer mysql_query, llamarlo nuevamente con la otra cadena:
    $result=mysql_query($cadena2, $enlace);

    El ‘reto’ sería armar la $cadena2, de la misma forma que se armaste $cadena.

    Saludos

  26. ELVIS dijo:

    Allinmi allinta ankay codigo ,,,
    En castellano el codigo funciona correctamente

  27. William dijo:

    Xevere el Script me saco de un apuro por q me taba haciendo bolas en importar a my base de datos MYSQL.

  28. Rafael R dijo:

    Señores es mas sencillo para los que necesiten solo manejar un tipo de carga delimitadora de csv…
    en la linea:
    $data = fgetcsv($handle, 1000, “,”)
    recuerden que el fgetcsv($handre, #delineas, «delimitado»
    el delimitador por defecto es la COMA «,» pero si están exportandolo desde excel, colocar simplemente un «;»
    la linea de arriba está bien pero para no dañar más la cabeza simplemente cambien la linea desde ahi….

    Probado y comprobado…

    • Andres dijo:

      estuve como media hora tratando de hacerlo correr y me bastó solo cambiar el delimitador a «;» y listo, funcionó perfecto. Graciass viejo!

  29. neo dijo:

    hola tengo este problema ejecuto el archivo y me sale esto en la apgina
    insert into almacen(Campo1,Campo2,Campo3,Campo4) values(‘zapatilla’,’azul’,’deporte’,’2000′);
    insert into almacen(Campo1,Campo2,Campo3,Campo4) values(‘a’,’negro’,’aso’,’500000′);
    insert into almacen(Campo1,Campo2,Campo3,Campo4) values(‘b’,’rosa’,’lavado’,’1000′);
    insert into almacen(Campo1,Campo2,Campo3,Campo4) values(‘c’,’naranjo’,’hola’,’1000000000′);

    Se insertaron 4 Registros en la tabla miTabla

    pero no insterta nada en la base de dato alquien me puede ayudar

  30. Romina dijo:

    hola tengo un problema con el codigo y lo necesito urgente de evrdad a q estoy haciendo un trabjo y necesito buscar un archivo en exel y exportalo a mysql pero probe el c0digo y me sale esto cuando lo ejecuto en la web

    insert into almacen(idAlmacen,articulo,color,material,precio) values(‘zapatilla;azul;deporte;2000’);
    insert into almacen(idAlmacen,articulo,color,material,precio) values(‘a;negro;aso;500000’);
    insert into almacen(idAlmacen,articulo,color,material,precio) values(‘b;rosa;lavado;1000’);
    insert into almacen(idAlmacen,articulo,color,material,precio) values(‘c;naranjo;hola;1000000000’);

    Se insertaron 5 Registros en la tabla miTabla

    y ya probe la consulta y noo se que puede ser si laguien me ayuda porfa urgente

    • Rauldeen dijo:

      esto lo necesitas hacer con un archivo excel o puede ser con un csv, yo tengo un codigo para enviar datos desde php hacia mysql pero solo con archivos csv. avisame si te sirve

  31. flako dijo:

    oyes karnal, creo k tengo el mismo problema de los demas, tu codigo si funciona, pero al consultar k en verdad se insertaron los datos en mysql, no aparece nada, como le hago?………
    o pasame el k ya funciona bien, si no es mucha molestia…….

    y de ante mano gracias x tu atencion…… espero tu respuesta, ojala me lo puedas enviar a mi correo, ya k es urgente

    • JoG dijo:

      @flako: Prueba las sugerencias que hay en los comentarios de este post. Por ejemplo, intenta «copiar» la cadena mostrada (algo asi como: «insert into table1….. etc» y pegarla en una consola de MySQL y ver si realmente está funcionando esa cadena, de lo contrario, allì te debería de indicar el error en la consola.

  32. franki dijo:

    Buenas este es el codigo que intento ejecutar pero me da error

    <?php
    function Conectarse()
    {
    if (!($link=mysql_connect("localhost","root",""))) {
    echo "Error conectando a la base de datos.";
    exit();
    }
    if (!mysql_select_db("precio",$link)) {
    echo "Error seleccionando la base de datos.";
    exit();
    }
    return $link;
    }

    $row = 1;
    $handle = fopen("datos.csv", "r");
    while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) {
    $num = count($data);
    $row++;
    $cadena = "INSERT INTO tarifa (familia,subfamlia,fabricante,codigo) VALUES ('$data[0]','$data[1]','data[2]','data[3]')";

    for ($c=0; $c < $num; $c++) {
    if ($c==($num-1))
    $cadena = $cadena."'".$data[$c] . "'";
    else
    $cadena = $cadena."'".$data[$c] . "',";
    }

    $cadena = $cadena.");";
    echo $cadena."»;

    $enlace=Conectarse();
    $result=mysql_query($cadena, $enlace);
    mysql_close($enlace);
    }

    fclose($handle);

    ?>

    este error

    Warning: fopen(datos.csv) [function.fopen]: failed to open stream: No such file or directory in C:\wamp\www\pr.php on line 24

    Warning: fgetcsv() expects parameter 1 to be resource, boolean given in C:\wamp\www\pr.php on line 25
    INSERT INTO tarifa (familia,subfamlia,fabricante,codigo) VALUES (»,»,’data[2]’,’data[3]’));

    Warning: fgetcsv() expects parameter 1 to be resource, boolean given in C:\wamp\www\pr.php on line 25
    INSERT INTO tarifa (familia,subfamlia,fabricante,codigo) VALUES (»,»,’data[2]’,’data[3]’));

    Warning: fgetcsv() expects parameter 1 to be resource, boolean given in C:\wamp\www\pr.php on line 25
    INSERT INTO tarifa (familia,subfamlia,fabricante,codigo) VALUES (»,»,’data[2]’,’data[3]’));

    Cual es mi fallo?
    contextar porfavor

    • JoG dijo:

      Por lo visto, el error que te indica es que no puede abrir el archivo «datos.csv» que es donde estan tus datos.
      Ya verificaste que ese es el nombre correcto de tu archivo? Ese archivo deberìa e estar colocado en la misma carpeta donde está ubicada la página .php que estas ejecutando (la que tiene el codigo)

    • JoG dijo:

      Además, creo que te faltó colocar el $ antes de data[2] y data[2]

  33. luisgota dijo:

    a mi me va perfecto.

    excelente aporte muchas gracias.

    saludos.

  34. ronny dijo:

    que tal amigo, muchas gracias por el aporte, solo que tengo un problemita,

    insert into general(folio, semana, corte, clave) values(388,26,16/Jun/10,’238 ‘);

    en values, 16/jun/10 necesito que sea «16/jun/10» y asi algunos campos de texto

  35. Bueno he estado mirando el codigo, efectivamente en el php no me sale error, pero tampoco modifica mi db:( no se que hacer !!!!

  36. JoG dijo:

    @Javier Vanegas: El error puede ser que la cadena que formaste contenga error sintáctico o algo por el estilo.
    Para conocer cuál es el error, copia la primera linea que te salio en tu página (algo así como «insert into…. etc») y pégala en una consola de MySQL para ejecutarla. allí te saldrá el error que tiene la cadena.

    Saludos

  37. kanaima dijo:

    bueno e hecho lo siguiente con creo que voy por buen camino mi problema es que no logro eliminar LA PRIMERA LINEA DE ENCABEZADO del la hoja de exel
    primero subo el archi del lado del cliente con un input=file y me queda asi:

    form action=»alum.php» method=»post» enctype=»multipart/form-data»>

    1.- busca el fichero con la extencion «.scv»
    2.- click en cargar SIE

    </form

    _______________________________________________
    esto LOPONGO DENTRO DE LA MISMA PAGINA DE MI FORM bueno subo el archivo al servidor con upload y lo paso de scv a txt luego lo export a mi tabla y borro el txt con unlink
    ______________________________________________

    <?php
    if (isset($_POST['enviar']))
    {
    $status = "";
    if ($_POST["action"] == "upload") {
    // obtenemos los datos del archivo
    $tamano = $_FILES["archivo"]['size'];
    $tipo = $_FILES["archivo"]['type'];
    $archivo = $_FILES["archivo"]['name'];

    if ($archivo != "") {
    // guardamos el archivo a la carpeta files
    $destino = "cie/".$archivo;
    if (copy($_FILES['archivo']['tmp_name'],$destino)) {
    $status = "Archivo subido: «.$archivo.»«;
    echo»$status»;
    } else {
    $status = «Error al subir el archivo»;
    echo»$status»;
    }
    } else {
    $status = «Error al subir archivo»;
    echo»$status»;
    }

    rename(«./cie/$archivo», «./cie/kanaima.txt»);

    $row = 1;
    $fp = fopen («cie/kanaima.txt»,»r»);
    while ($data = fgetcsv ($fp, 1000, «;»))
    {
    $num = count ($data);
    print » «;
    $row++;
    $insertar=»INSERT INTO alumno (control,nombre,carrera,turno,profesor,creditos) VALUES (‘$data[0]’,’$data[1]’,’$data[2]’,’$data[3]’,’$data[4]’,’$data[5]’)»;
    mysql_query($insertar);
    }
    fclose ($fp);

    unlink(‘./cie/kanaima.txt’);
    echo «Los Datos Han Sido Cargados a La Tabla Alumno»;
    }
    ________________________________________________________—

    }
    }

    ?>

    y eso es todo si es mucho trajin pero funciona

  38. Jorge M dijo:

    Muchas gracias me sirvio mucho tu codigo.
    Se me habia ocurrido algo similar pero me gusto mas tu idea buen trabajo

  39. Carlos dijo:

    tu codigo no anda.Revisalo mejor antes de publicar algo, para evitar perder mi tiempo. Gracias

  40. carlos dijo:

    disculpa y a la hora que halla una linea con error como hago para que no guarde esa linea y siga con las demas?

  41. Andres Pachon dijo:

    hola,
    de casualidad tienes uno de como meter eso dentro de un boton?

  42. roger dijo:

    HOLA QUE TAL SOLO QUISERA PEDIRTE SI ME PUEDES PASAR UNA APLICACION QUE MANIPULE LA CARGA MASIVA DE DATOS COM CSV (PHP – MYSQL)
    MI CORREO ES armijo.sistemas.2010.20@gmail.com
    te agradeceria mucho compartir esta informacion

  43. consulta dijo:

    <?php

    /* Código que lee un archivo .csv con datos, para luego insertarse en una base de datos, vía MySQL
    * Gracias a JoG
    * https://gualinx.wordpress.com
    */

    function Conectarse() //Función para conectarse a la BD
    {
    if (!($link=mysql_connect("localhost","root","xxxxxxxxx"))) { //Cambia estos datos
    echo "Error conectando a la base de datos.";
    exit();
    }
    if (!mysql_select_db("produccion",$link)) {
    echo "Error seleccionando la base de datos.";
    exit();
    }
    return $link;
    }

    $row = 2;
    $handle = fopen("informe/probando.csv", "r"); //Coloca el nombre de tu archivo .csv que contiene los datos
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { //Lee toda una linea completa, e ingresa los datos en el array 'data'
    $num = count($data); //Cuenta cuantos campos contiene la linea (el array 'data')
    $row++;
    $cadena = "insert into prueba(nombre,email,telefono) values("; //Cambia los valores 'CampoX' por el nombre de tus campos de tu tabla y colócales los necesarios

    for ($c=0; $c < $num; $c++) { //Aquí va colocando los campos en la cadena, si aun no es el último campo, le agrega la coma (,) para separar los datos
    if ($c==($num-1))
    $cadena = $cadena."'".$data[$c] . "'"; //
    else
    $cadena = $cadena."'".$data[$c] . "',";
    }

    $cadena = $cadena.");"; //Termina de armar la cadena para poder ser ejecutada
    echo $cadena."»; //Muestra la cadena para ejecutarse

    $enlace=Conectarse();
    $result=mysql_query($cadena, $enlace); //Aquí está la clave, se ejecuta con MySQL la cadena del insert formada
    mysql_close($enlace);
    }

    fclose($handle);

    ?>

    no me da error solo no me inserta.
    en unas de las pruebas haciendo el insert asi…
    $cadena = «insert into prueba(nombre,email,telefono) values(‘$data[0]’,’$data[1]’,’$data[3]’)»);
    en la tabla de db mysql solo queda toda la informacion en la primera posicion

    bueno si alguien tiene el codigo completo por favor responda

  44. JoG dijo:

    Qué es lo que te aparece en pantalla? es lo que pusiste allí?
    $cadena = “insert into prueba(nombre,email,telefono) values(‘$data[0]‘,’$data[1]‘,’$data[3]‘)”);

    Si es así, veo que tienes el error que no está imprimiendo los valores que deseas insertar, ya que aparece ‘$data[0]‘ En vez de eso te debe de aparececer «Juanito el Caminante» y así con los otros valores.

    toma en cuenta que la variable $data es la que contiene los campos, la variable $c es la que tiene UN caracter del campo.

    Qué es lo que te imprime en pantalla? intenta copiar una linea de esas, y luego la ejecutas en una consola SQL para ver si hay algun error de sintaxis u otro error, segun SQL
    Saludos!

  45. Hola!
    muchas gracias por este aporte. me sirvió mucho, sin problemas, muy claro
    solo hay que modificar los valores de la base de datos, usuario, contraseña, la tabla…creo que es todo!!

    🙂

  46. elinconforme dijo:

    una maravilla tu codigo, muchisimas gracias, Y que atento con todos y que mira que no saben seguir indicaciones, ERES UN BUEN SOPORTE jajaja.
    ¿ Oye pero como podria hacer si que el archivo no lo tome de una ruta, si no que lo cargue de un formulario. Tienes alguna idea ??

  47. Juan Acosta dijo:

    Muy bueno tu codigo, y bastante bien explicado, mil gracias por el aporte, para los que no les ha funcionado, revisar bien los datos de la conexion, campos de la tabla, ubicación del fichero origen, por que la verdad funciona muy bien, sólo una pequeña queja si me permite el autor, es que se me demora un poco cargando ficheros de unas 15000 filas, no se si se podría mejorar algo?, igual mil gracias por el aporte, saludos

  48. francisco Rogelio dijo:

    se puede hacer eso con jsp o servlets¡? ayuda lo necesito con jsp o servlets

  49. Marina dijo:

    Estuve horas probando hacer esto mismo sin php, es decir, mediante la interfaz de phpmyadmin, y no tuve éxito, hasta que probe con tu código y me fue de maravillas, voy a agregar tu web a mis favoritos. Muchas gracias por compartir!!!

  50. Bertoldo dijo:

    A mi me funciono de Maravilla!!!! Saludos, Grx por la aoportación.. ( tenia un detalle pero correspondia al Numero de columnas que habia determinado)

  51. mavercom dijo:

    funciona perfecto, gracias por el código

  52. Hola el script funciona a la perfección.

    A las personas que trabajen con MAC os X, cuando guarden el archivo .xls a .csv tienen que guardarlo como : » valores separados por comas de windows (.csv)» de lo contrario, captura 5 o mas datos en un registro.

    Muchas gracias por el Script amigo, tenia que capturar 3,350 registros, aun no logro guardar todos, me guarda como 250 datos pero con un poquito de trabajo lograre capturar todos los datos.

    Saludos y muchas gracias.

  53. jumabu dijo:

    Señores, yo lo he solucionado usando el original, pero toqué un poco el código!

    es bien simple, el error ocurre al final de la cadena porque nos inserta un registro mas pero vacio, veamos este ejemplo:
    insert into mi_tabla(campo1, campo2, campo3,) values(‘dato1′,’dato2′,’dato3’,»)

    Después de dato3 hay una coma y un registro vacío, por eso no nos carga nada en la base porque tenemos (según este ejemplo) 3 campos en la base de datos y 4 registros para ser cargados ¿se entendió?
    Cómo lo solucioné?
    Agarré mi base de datos y le agregué un campo mas!!!!
    Me quedó así:

    insert into mi_tabla(campo1, campo2, campo3,campo4) values(‘dato1′,’dato2′,’dato3’,»)

    y así me carga todo perfectamente, el 4 campo siempre queda vacío!
    Si tienen que cargar 20 campos: el excell tendrá 20 campos y la tabla mysql 21 (mas el id 22)
    Espero que les sea de utilidad!!!!

    Saludos!!! Pego el código completo

    <?php

    function Conectarse() //Función para conectarse a la BD
    {
    if (!($link=mysql_connect("localhost","miusuario","mipassword"))) { //Cambia estos datos
    echo "Error conectando a la base de datos.";
    exit();
    }
    if (!mysql_select_db("mibd",$link)) {
    echo "Error seleccionando la base de datos.";
    exit();
    }
    return $link;
    }

    $row = 1;
    $handle = fopen("datos.csv", "r"); //Coloca el nombre de tu archivo .csv que contiene los datos
    while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) { //Lee toda una linea completa, e ingresa los datos en el array 'data'
    $num = count($data); //Cuenta cuantos campos contiene la linea (el array 'data')
    $row++;
    $cadena = "insert into miTabla(Campo1,Campo2,Campo3,Campo4) values("; //Cambia los valores 'CampoX' por el nombre de tus campos de tu tabla y colócales los necesarios y agrega un campo más en tu base de datos y obviamente lo cargas aquí tambien!
    for ($c=0; $c < $num; $c++) { //Aquí va colocando los campos en la cadena, si aun no es el último campo, le agrega la coma (,) para separar los datos
    if ($c==($num-1))
    $cadena = $cadena."'".$data[$c] . "'";
    else
    $cadena = $cadena."'".$data[$c] . "',";
    }

    $cadena = $cadena.");"; //Termina de armar la cadena para poder ser ejecutada
    echo $cadena."»; //Muestra la cadena para ejecutarse

    $enlace=Conectarse();
    $result=mysql_query($cadena, $enlace); //Aquí está la clave, se ejecuta con MySQL la cadena del insert formada
    mysql_close($enlace);
    }

    fclose($handle);

    ?>
    Se insertaron Registros en la tabla miTabla

    Saludos!

  54. LOBO dijo:

    ALGUIEN ME PODRIA PASAR UN CONTROL ESCOLAR

  55. Richart dijo:

    hola alguien me puede ayudar, es que toda la linea de datos me la guarda en una sola casilla, osea el problema es con la estensión .csv por q no los esta separando por comas, sera la version del excel o existe otro forma de archivo. gracias si alguien me colobora.

  56. Rafa dijo:

    Estimado:

    Necesito subir datos numéricos y varchar, pero el script me arma todo con comillas simples y los datos numéricos no lo llevan, por lo que me genera error. cómo lo modifico para que pueda hacerlo?

    Gracias y saludos.

  57. Aqui les dejo este ejemplo que a mi me funcionó:

    <?php

    /* Código que lee un archivo .csv con datos, para luego insertarse en una base de datos, vía MySQL
    * Gracias a JoG
    * https://gualinx.wordpress.com
    */
    function Conectarse() //Función para conectarse a la BD
    {
    if (!($link=mysql_connect("localhost","root","12345"))) { //Cambia estos datos
    echo "Error conectando a la base de datos.";
    exit();
    }
    if (!mysql_select_db("sed",$link)) {
    echo "Error seleccionando la base de datos.";
    exit();
    }
    return $link;
    }
    $row = 1;

    $archivo = $_GET['archivo'];// En mi caso, previamente subí el archivo .cvs con los datos, mediante un insert a una base de datos y recuperé el nombre del archivo mediante un GET

    $handle = fopen($archivo, "r");
    while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) { //Lee toda una linea completa, e ingresa los datos en el array 'data'
    $num = count($data); //Cuenta cuantos campos contiene la linea (el array 'data')
    $row++;
    $cadena = "INSERT INTO usuarios (rfc, rfc_13, usuario_curp, usuario_idrusp, usuario_paterno, usuario_materno, usuario_nombre, usuario_nombre_completo, puesto_nivel, puesto_nombre, puesto_codigo, puesto_tipo, puesto_ur, rfc_jefe_2, rfc_jefe_3, id_descripcion, evaluado, capturado, correo, adscripcion, estudios, pass, nivel_acceso, nivel_eap, evalua_colectivas) VALUES (";

    for ($c=0; $c < $num; $c++) { //Aquí va colocando los campos en la cadena, si aun no es el último campo, le agrega la coma (,) para separar los datos

    //Determino las variables para la sustitucion al momento de generarse la cadena. OJO, debe ir despues de cerar $c, si no no funciona.
    $error = ",";
    $correcto ="', '";
    $data[$c]=str_replace($error, $correcto, $data[$c]);

    if ($c==($num-1))
    $cadena = $cadena."'".$data[$c] . "' ";
    else
    $cadena = $cadena."'".$data[$c] . "', ";
    }

    $cadena = $cadena.");"; //Termina de armar la cadena para poder ser ejecutada
    echo $cadena."»; //Muestra la cadena para ejecutarse

    $enlace = Conectarse();
    $result=mysql_query($cadena, $enlace)or die(mysql_error()); //Aquí está la clave, se ejecuta con MySQL la cadena del insert formada, en caso contrario muestra el error
    mysql_close($enlace);
    }
    fclose($handle);

    ?>

    Se insertaron Registros en la tabla Usuarios

  58. Nicolas dijo:

    Hola, muchas gracias por el codigo, despues de tanto buscar encontre uno que funcione.
    Una consulta, como puedo cuando el nombre del archivo es variable? O sea que no tiene siempre el mismo nombre?
    Gracias

  59. jumabu dijo:

    ja! desde ya te digo que estás en problemas!!! si mantienes el nombre funciona perfecto, lo que tendrías que hacer es agregar un campo al formulario donde escribas el nombre del archivo y luego lo pasas por url como variable para que sea reemplazado en lugar de «datos.csv».

  60. Raul dijo:

    Hola, fue de mucha ayuda, funciono a la perfección……….

  61. Warning: fopen(Libro1.txt): failed to open stream: No such file or directory in C:\Users\ESSISPS\Desktop\xampp-portable\htdocs\upload2.php on line 24

    ERROR ERROR
    ayuda!!!

  62. Dulce Cervantes dijo:

    Hola…
    Disculpa solamente sustitui los valores del nombre del archivo csv, de la base de datos y de los campos que se van a insertar en la tabla de mysql ejecuto el php y se cicla me da un error de tiempo de ejecusion excedido.

  63. Dulce Cervantes dijo:

    Me arroja otro error

    Warning: mysql_connect() [function.mysql-connect]: [2002] Sólo se permite un uso de cada dirección de socket (protocolo/dirección de red/puerto) (trying to connect via tcp://localhost:3306) in C:\Archivos de programa\Ampps\www\phpmysql\csvdata.php on line 5

    Warning: mysql_connect() [function.mysql-connect]: Sólo se permite un uso de cada dirección de socket (protocolo/dirección de red/puerto) in C:\Archivos de programa\Ampps\www\phpmysql\csvdata.php on line 5
    Error conectando a la base de datos.

    & no tengo ni la mas minima idea de porque surge o como se arregla

  64. Dulce Cervantes dijo:

    Aqui esta el script php que me funciono para almacenar registros del csv en una tabla en una base de datos con mysql

    <?php

    set_time_limit(0); //Establece el tiempo limite de ejecucion del script como mi maquina esta demasiado lenta y me arrojaba un error de tiempo maximo de ejecusion asi que le puse el 0, ya que con el 0 no tiene limite de ejecucion, sin embargo puedes ponerle, 30 o 60 segundos de ejecucion.

    function Conectarse() //Función para conectarse a la BD
    {
    if(!($link= mysql_connect("servidor","usuario","password"))) { //Cambia estos datos
    echo "Error conectando a la base de datos.";
    exit();
    }
    if (!mysql_select_db("test",$link)) {
    echo "Error seleccionando la base de datos.";
    exit();
    }
    return $link;
    }
    $enlace=Conectarse(); //Manda llamar la funcion de conectarse para que se conecte antes de que entre al ciclo del while
    $row = 1;
    $handle = fopen("nombre_archivo.csv", "r"); //Coloca el nombre de tu archivo .csv que contiene los datos, y para los que no sabian como yo xD la "r" indica que el archivo sera de lectura

    $result=mysql_query("delete from boyas"); //Elimina todos los registros almacenados en la BD para volverlos a ejecutar con el while

    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { //Lee toda una linea completa, e ingresa los datos en el array 'data'

    $num = count($data); //Cuenta cuantos campos contiene la linea (el array 'data')
    $row++;
    $cadena = "insert into nombre_tabla (campos) values ("; //Cambia los valores 'CampoX' por el nombre de tus campos de tu tabla y colócales los necesarios

    for ($c=0; $c < $num; $c++) { //Aquí va colocando los campos en la cadena, si aun no es el último campo, le agrega la coma (,) para separar los datos

    $data[$c]=str_replace('\'',' ',$data[$c]); //remplaza comilla de texto fuente por espacio en blanco

    if ($c==($num-1))
    $cadena = $cadena."'".$data[$c] . "'";
    else
    $cadena = $cadena."'".$data[$c] . "',";
    }

    $cadena = $cadena.")"; //Termina de armar la cadena para poder ser ejecutada
    echo $cadena."»; //Muestra la cadena para ejecutarse

    $result=mysql_query($cadena); //Aquí está la clave, se ejecuta con MySQL la cadena del insert formada

    }
    mysql_close($enlace); //Ya que termina el ciclo cierra la conexion con la base de datos.
    fclose($handle);

    ?>

    Se insertaron Registros en la tabla «x»

  65. Hola amigos, despues de dar vueltas buscando en la red he dado con esta maravillosa información, quisiera saber si me podeis ayudar, ya que estoy atascado con esta situación, despues de leer todos los comentarios de este blog, quiero mostrarles mi caso y ver si encuentro la solución, mi caso es que no se absolutamente nada de programación y he ido encontrando cosas de aqui y de alla, os copio mi codigo pero explico antes mi caso,

    me gustaria que la llamada fuese automatica a una CSV externo mediante url, leyera todos los datso de este csv y los traspasara a mi base de datos, creara los que no existen y actualizara solo dos campos, cantidad de stock, y si no hay stock lo desabilitara.

    he llegado hasta aqui, pero no se si esta correcto por favor alguien me pudiera ayudar?? gracias

    categoryImport();
    break;

    case 1:
    loadProductsPost();
    $import->productImport();
    break;

    default:
    die();
    break;
    }

    function loadCategoriesPost() {
    $_POST = array (
    ‘tab’ => ‘AdminImport’,
    ‘skip’ => ‘0’,
    ‘csv’ => ‘cat.csv’,
    ‘convert’ => »,
    ‘entity’ => ‘0’,
    ‘separator’ => ‘;’,
    ‘multiple_value_separator’ => ‘,’,
    ‘import’ => ‘Importar datos CSV’,
    ‘type_value’ =>
    array (
    0 => ‘id’,
    1 => ‘active’,
    2 => ‘name’,
    3 => ‘parent’,
    4 => ‘description’,
    5 => ‘meta_title’,
    6 => ‘meta_keywords’,
    7 => ‘meta_description’,
    8 => ‘link_rewrite’,
    9 => ‘image’,
    ),
    );
    }

    function loadProductsPost() {
    $_POST = array (
    ‘tab’ => ‘AdminImport’,
    ‘skip’ => ‘0’,
    ‘csv’ => ‘pro.csv’,
    ‘convert’ => »,
    ‘entity’ => ‘1’,
    ‘separator’ => ‘;’,
    ‘multiple_value_separator’ => ‘,’,
    ‘import’ => ‘Importar datos CSV’,
    ‘type_value’ =>
    array (
    0 => ‘id’,
    1 => ‘active’,
    2 => ‘name’,
    3 => ‘category’,
    4 => ‘price_tex’,
    5 => ‘tax_rate’,
    6 => ‘wholesale_price’,
    7 => ‘on_sale’,
    8 => ‘reduction_price’,
    9 => ‘reduction_percent’,
    10 => ‘reduction_from’,
    11 => ‘reduction_to’,
    12 => ‘reference’,
    13 => ‘supplier_reference’,
    14 => ‘supplier’,
    15 => ‘manufacturer’,
    16 => ‘ean13’,
    17 => ‘ecotax’,
    18 => ‘weight’,
    19 => ‘quantity’,
    20 => ‘description_short’,
    21 => ‘description’,
    22 => ‘tags’,
    23 => ‘meta_title’,
    24 => ‘meta_keywords’,
    25 => ‘meta_description’,
    26 => ‘available_now’,
    27 => ‘available_later’,
    28 => ‘image’,
    29 => ‘no’,
    ),
    );
    }
    ?>

  66. Elwyn dijo:

    Disculpa resulta que tengo 8000 registro que insertar y me marca error
    Fatal error: Maximum execution time of 30 seconds exceeded in C:\wamp\www\SoftUnicorn\index.php on line 101 es por que tarde en la insercion de mis registros?

    • Jog dijo:

      Sí, lo que puedes hacer es: NO intentar ingresar los registros desde el PHP, sino únicamente que el PHP te sirva como rutina para ARMAR tu cadena SQL. Una vez armada, puedes COPIAR las cadenas SQL generadas en la pantalla, y pegarlas en tu consola de SQL.
      Eso hice yo con 60mil registros, y no dió problema.

  67. Lemy dijo:

    GENTE: hoy en dia esto se puede hacer desde el PHPmyAdmin , usando Importar -> CSV.
    Saludos.

  68. Hola buen día, gracias por tu aporte me ha sido de gran ayuda, sin embargo en mi caso del archivo csv, solo me inserta el último registro, y mi archivo de prueba contiene 1000. Dejo mi código!
    <?php
    include ('conect.php');
    require ('conect.php');
    $fila = 1;
    $archivo = $_FILES['excel']['name'];

    if (($gestor = fopen("$archivo", "r")) !== FALSE) {
    while (($datos = fgetcsv($gestor, 1000, ";")) !== FALSE) {
    $numero = count($datos);
    echo " $numero campos en la línea $fila: \n»;
    $fila++;

    $cadena = «insert into consumos (CIF_Cliente, Cargo, Servicio, Desc_Servicio, Multiconexion, Conexion, Desc_Cod_Trafico, Ambito_de_Trafico, Operador, Numero_LLamadao, Numero_Emisor, Destino, Fecha_Llamada, Hora_Inicio, Duracion, Tarifa, Importe) values («;for ($c=0; $c < $numero; $c++) {

    if ($c==($numero-1))
    $cadena = $cadena."'".$datos[$c] . "'";
    else
    $cadena = $cadena."'".$datos[$c] . "',";
    }
    $cadena = $cadena.");"; //Termina de armar la cadena para poder ser ejecutada
    echo $cadena."»;

    }

    $result=mysql_query($cadena)or die(mysql_error()); //Aquí está la clave, se ejecuta con MySQL la cadena del insert formada, en caso contrario muestra el error
    mysql_close();
    }
    fclose($gestor);
    ?>

  69. Después de buscar otras opciones finalmente pude realizar la carga completa con el siguiente código. Espero que les funcione. Gracias!

  70. Gastón dijo:

    Muchas gracias por el código, funciona a la perfección! Una consulta, se puede hacer que cuando ejecutamos el PHP en lugar de subir todo lo que se encuentra en el CSV, detecte si existen filas que ya se cargaron en la tabla para que no las duplique? Quiero utilizarlo para actualizar una base de datos, y la idea es que el CSV se actualice todo el tiempo, pero si lo hago de esta manera cada vez que suba el CSV me va a cargar lo nuevo más todo lo anterior que ya está en la base. Desde ya, gracias miles!!!

    • JoG dijo:

      Antes de hacer el insert tienes que hacer un select algo como:
      select llave_campo1, llave_campo2 from nombreTabla where llave_campo1 = valor1Ainsertar and llave_campo2 = valor2Ainsertar;

      Hacer esa consulta, luego en PHP, revisar si trae datos, SI NO TRAE datos, hacer el insert que ya tienes, (Imprimirlo y luego insertarlo). De lo contrario, si devuelve datos, entonces no hacer nada, y continuar con el siguiente row

    • JoG dijo:

      Antes de hacer el insert tienes que verificar si ya existe tal informaci[on con un select algo como:
      select llave_campo1, llave_campo2 from nombreTabla where llave_campo1 = valor1Ainsertar and llave_campo2 = valor2Ainsertar;

      Hacer esa consulta, luego en PHP, revisar si trae datos, SI NO TRAE datos, hacer el insert que ya tienes, (Imprimirlo y luego insertarlo). De lo contrario, si devuelve datos, entonces no hacer nada, y continuar con el siguiente row

  71. Excelente aporte me sirvió bastante

  72. luis dijo:

    hola. me funcióno ok. pero necesito actualizar los valores de una misma fila. hay alguna forma de hacerlo. soy principiante en esto. desde ya agradezco su ayuda.

  73. easteteb dijo:

    Hola JoG, este script me lee desde la fila 0 de mi CSV, es decir, me importa los encabezados. Tengo 2 consultas:
    1. ¿Cómo sería para que me importe desde la fila 1 que viene a ser el primer registro?
    2. Tengo un campo fecha que el CSV es del tipo dd/mm/YY y cuando lo importa a mysql lo deja como 0000-00-00. ¿Cómo se procede en este caso?

    Gracias por tu respuesta anticipada.

  74. Cristian Carmona dijo:

    Buenísimo , no me funciono pero me dio una idea clara y baje el tiempo de insert de 5 minutos a 6 segundos

Replica a Luis Fernando Caraballo Cancelar la respuesta