Import fichiers csv dans une base de données

Soyez le premier à donner votre avis sur cette source.

Vue 11 262 fois - Téléchargée 1 419 fois

Description

Salut...
Je suis actuellement en stage.
Durant celui-ci je doit permettre l'automatisation d'ajout de materiel dans une Base De Données
J'ai utilisé le script de "caviar"
"http://www.phpcs.com/codes/IMPORT-CSV-VERS-BDD-MYSQL-AVEC-CHOIX-CHAMPS_39220.aspx"
Pour mes besoins, j'ai débugué et optimisé le script.
Je me permet donc de déposé le code source mis à jour.
@+

Source / Exemple :


<html>
<head>
<script language="JavaScript" type="text/JavaScript">
<!--
function MM_jumpMenu(targ,selObj,restore){ //v3.0
  eval(targ+".location='"+selObj.options[selObj.selectedIndex].value+"'");
  if (restore) selObj.selectedIndex=0;
}
//-->
</script>
<LINK rel="StyleSheet" href="import.css" type="text/css" />
</head>
<body>
<?php
// Liste les données de la table
// -------------------------------------------
include ('./conf/config.inc.php');
include ('./functions/mysql.php');
?>

<?php
 // on affiche les tables de la bdd
//pour que ce script fonctionne il faut au moins un enregistrement dans la table sélectionnée
function display_one_table($tablename){
//$query="show fields from $tablename";
//$result=mysql_query($query);
$result = requette ("show fields from $tablename");
$rows = mysql_num_rows($result);
?>

<table width ="95%" cellspacing="0" cellpadding="4" border="1" style="font-family:courier new;font-size:12px" align="center">
<tr style="background-color:silver">
<th colspan="6" style="font-size:14px">Informations sur la table <i><?php echo $tablename?></i></th>
</tr>
<tr style="background-color:#ddd;font-size:12px">
<td>Field</td>
<td>Type</td>
<td>Null</td>
<td>Key</td>
<td>Default</td>
<td>Extra</td>
</tr>
<?php
while ($row = mysql_fetch_row($result)) {
?>
<tr style="background-color:<?php echo ($i++ %2 == 0 ? '#cee8ce' : '#f0f0f0') ?>">
<td><?php echo $row[0] ?>&nbsp;</td>
<td><?php echo $row[1] ?>&nbsp;</td>
<td><?php echo $row[2] ?>&nbsp;</td>
<td><?php echo $row[3] ?>&nbsp;</td>
<td><?php echo $row[4] ?>&nbsp;</td>
<td><?php echo $row[5] ?>&nbsp;</td>
</tr>
<?php
}
?>
</table>
<br />
<?php
}

///////////////////////
$result_tables = requette ("SHOW TABLES FROM `".$bdd."`");
?>

<form action="" name="form_bdd" id="form_bdd" method="post" enctype="multipart/form-data">
<h3>Table de la base de donnee qui va recevoir l'import</h3>
<select name="table">
<option value="" <?php if (!isset($_POST['table'])){ echo'selected'; } ?> >Choisissez une table</option>
<?php
while ($row = mysql_fetch_row($result_tables)) {
//   echo "Table : {$row[0]}\n"; // Morceau de code inutile non ? Du moins incorrect !

   echo " <option ";
   if (isset($_POST['table']) && $row[0]==$_POST['table']){ echo'selected '; }
   echo "value=\"".$row[0]."\">Table : ".$row[0]."</option>";  
  echo "\n";
}
?>
</select>
<p style="font-weight:bold">Fichier CSV ou TXT au format csv</p>
<p style="color:#00f;font-weight:bold">Preparation du fichier : </p>
<p><input type="file" name="fichiercsv" size="16">
Delimiteur : <select name="del">
<option value=";" selected>; Point virgule</option>
<option value=",">, Virgule</option>
<option value=":">: Deux points</option>
<option value="-">- Tiret</option>
<option value="/">/ Slash</option>
<option value="|">| Barre</option>
<option value="#"># Diese</option>
</select>
</p>
<p>
<input type="hidden" name="etape2" value="1">
<input type="submit" value="Correpondance des champs">
</p>
</form>

<?php if (isset($_POST['table']) && $_POST['table'] !="" && isset($_POST['etape2'])) {
$del = $_POST['del'];
if( empty($_FILES['fichiercsv']['tmp_name'])){
exit('<p style="color:red;font-weight:bold">Vous n\'avez pas choisi de fichier a uploader</p></body></html>.');
}
?>
<form action="" name="form_import" id="form_import" method="post">
<?php
// on crée cette variable ici avant de faire le test car elle peut servir ? la suppression aussi

$content_dir = 'tmp/'; // dossier où sera déplacé le fichier

//---------------------

      $tmp_file = $_FILES['fichiercsv']['tmp_name'];
    
       if( !is_uploaded_file($tmp_file) )
       {
           exit("Le fichier est introuvable.<br /> Vous n'avez pas choisi de fichier a uploader.");
       }
    
       // on v?rifie maintenant l'extension
       //$type_file = substr($_FILES['fichier']['name'], strrpos($_FILES['fichier']['name'], "."));
       $type_file = $_FILES['fichiercsv']['type'];
   //echo 'nom du fichier :'.$tmp_file.'<br />';
       //echo  'type du fichier : '.$type_file.'<br />';
  

$extensions_valides = array( 'csv' , 'txt' );
$extension_upload = substr(  strrchr($_FILES['fichiercsv']['name'], '.')  ,1);
if ( in_array($extension_upload,$extensions_valides) ){

       // on copie le fichier dans le dossier de destination
       $name_file = $_FILES['fichiercsv']['name'];
    
       if( !move_uploaded_file($tmp_file, $content_dir . $name_file) )
       {
           exit("Impossible de copier le fichier dans $content_dir");
       }
       ?>
<p>Le fichier <span style="color:#00f"><strong><?php echo '<a href="'.$content_dir.'/'.$name_file.'">'.$name_file.'</a>'?></strong></span> a bien ete uploade</p>
       <?php
   display_one_table($_POST['table']);
   echo '<p>&nbsp;&nbsp;&nbsp;</p>';

} else {
?>
<p style="color:red;font-weight:bold">Extension incorrecte. Vous pouvez uploader des <strong>csv, txt. </strong></p>
<?php
}

if(file_exists("$content_dir"."$name_file")) {

//on lis la 1ere ligne pour g?n?rer lles listes
$fp = fopen("$content_dir"."$name_file", 'r');
$str="";
$cpt=0;

$str .= fgets($fp, 99000);
//echo $str;
$str=trim($str);
if (substr($str,-1,1) != $del){
$str .= $del ;
}
//
$tabcsv = explode ($del, $str);
//echo $str;

fclose ($fp);
//on suppr les espaces
//print_r($tabcsv);
?>
<table  align="center" cellspacing="0" cellpadding="2" border="1" style="font-family:courier new;font-size:12px" >
<tr align="center" style="font-weight:bold">
<td>Champ de la table</td>
<td>Champ du fichier CSV</td>
</tr>

<?php
//génération des listes de gauche avec les champs de la bdd
$resQuery = requette("SHOW FIELDS FROM ".$_POST['table']." FROM ".$bdd);
$fields = mysql_num_rows($resQuery);

// g?n?ration des listes ---------------------------
//fonction permettant de récuperer les valeurs contenues dans le fichier csv 
function csv ($j, $tabcsv){
?>
<td>
<select name="colonecsv<?php echo $j ; ?>">
  <option value="" >AUCUNE VALEUR</option>

<?php

// on affiche les champs de la table choisie

  // titre des colonnes

  $i = 0;
  while ($i < count($tabcsv)) {
echo "<option ";
    if ($i == $j){ echo 'selected '; }
echo "value=\"";
echo $i;
echo "\">";
echo $tabcsv[$i];
echo "</option>";  
echo "\n";
   $i++;
  }
			
  echo "\n";
?>   </select>
</td>
<?php

 }

 
if (mysql_num_rows($resQuery) != 0) {
$j = 0;
while ($j < $fields) {
?>
<tr><td>
<select name="colone<?php echo $j ; ?>">
<option value="" <?php if (!isset($_POST['colone0'])){ echo'selected'; } ?> >Choisissez une colonne</option>
<?php

// on affiche les champs de la table choisie

  // titre des colonnes

  $i = 0;
    while ($i < $fields) {
    $savior = mysql_result($resQuery, $i);
echo '<option value="'.$savior.'"';
echo ($i == $j ? ' selected>' : '>');
echo $savior.'</option>';
echo "\n";
    $i++;
  }
  echo "\n";

?></select>
</td>
<?php
//appel de la fonction csv
csv($j, $tabcsv);
?>

<?php  
$j++;
} // fin while j
 
} 

} else {
echo 'erreur. Fichier csv mal uploadé.<p>&nbsp;&nbsp;&nbsp;</p>';
}

   ?>
</td>
</tr>
<tr>
<td colspan="2">
<input type="hidden" name="content_dir" value="<?php echo $content_dir ; ?>">
<input type="hidden" name="name_file" value="<?php echo $name_file ; ?>">
<input type="hidden" name="table" value="<?php echo $_POST['table'] ; ?>">
<input type="hidden" name="fields" value="<?php echo $fields ; ?>">
<input type="hidden" name="del" value="<?php echo $_POST['del'] ; ?>">
<input type="hidden" name="nb_colones_csv" value="<?php echo count($tabcsv)-1 ; ?>">
<input type="hidden" name="listeok" value="1"></td></tr>
<tr>
<td align="center" colspan="2">
<input  type="submit"  value =" Importer dans la BDD">
</tr>
</td>
</table>
</form>
<?php } //fin du if isset
else if (isset($_POST['etape2'])){
?>
<p style="color:red;font-weight:bold">Vous n'avez pas choisi de table ou importer les donnees !</p>
<?php
}
?>

<?php if (isset($_POST['listeok'])){
echo '<strong>Traitement du fichier CSV</strong> <br /><br />';
$del = $_POST['del']; //choix du d?limiteur
$content_dir = $_POST['content_dir'];
$name_file = $_POST['name_file'];
$table = $_POST['table'];
//nb de champs dans la table
$fields = $_POST['fields'];
$nb_colones_csv = $_POST['nb_colones_csv'];

//on lis la 1ere ligne pour g?n?rer lles listes
$fp = fopen("$content_dir"."$name_file", 'r');
$str="";
$cpt=0;
while (!feof($fp)) {
$str = fgets($fp, 99000);

//on ?vite les lignes vides
if(!empty($str)){
//si on a pas de ; ? la fin d'une ligne on en ajoute une
//$str = "azerty";
$str=trim($str);
//echo 'dernier car de la ligne = '.substr($str,-1,1).'<br>';
if (substr($str,-1,1) != $del){
$str .= $del ;
}
//on remplace les ' par \'
$str = str_replace ("'","\'",$str);

$nbcar = strlen($str);
//on cherche les caract?res de s?paration
//echo 'nb de char sur la ligne='.$nbcar.'<br>';
$valligne [] ="";
// pour placer la valeur chaque fois dans la case suivante du tableau temporaire valligne
$vallignecpt = 0;

//PARSAGE DES VALEURS
// SI ON DEBUTE PAR UN "

while ($nbcar != 0){

$pos1=0;
if (substr($str,0,1) == '"'){
$pos1 = 1;
$trouve=0;
for ($pos=0 ; $trouve!= 1; $pos++){
$sepa = substr($str,$pos,2);
//echo 'caractere analis?='.$sepa.'<br>';
if( $sepa== '"'.$del){
$pos2 = $pos; //on r?cup?re la position du debut de l'enregistrement
//echo 'pos1='.$pos1.'<br>';
//echo 'pos2='.$pos2.'<br>';
$long = $pos2 - $pos1; //longueuur de la chaine à extraire
$tempstr = substr($str, $pos1, $long ); //on recup le reste de la ligne
//echo 'compteur ='. $vallignecpt.'<br>';
//on regarde si on a remplis le champ pour forcer la valeur
$tempforce = 'force'.$vallignecpt;
if (isset($_POST[$tempforce]) && $_POST[$tempforce] != ""){
$valligne [$vallignecpt] = trim($_POST[$tempforce]);
} else {
//sinon on remplis avec la valeur trouvée
$valligne [$vallignecpt] = $tempstr ;
}
$vallignecpt++;
//echo "<strong>Valeur ajoutée=</strong>".$tempstr.'<br><br>';
$trouve=1;
$str = substr ($str, ($pos2+2));
//echo 'Nouvelle Phrase='.$str.'<br>';
$nbcar = strlen($str);
}
}
} else {
$pos1 = 0;
$trouve=0;
for ($pos=0 ; $trouve!= 1; $pos++){
$sepa = substr($str,$pos,1);
//echo 'caractere analis?='.$sepa.'<br>';
if( $sepa == $del){
$pos2 = $pos; //on r?cup?re la position du debut de l'enregistrement
//echo 'pos1='.$pos1.'<br>';
//echo 'pos2='.$pos2.'<br>';
$long = $pos2 - $pos1; //longueuur de la chaine ? extraire
$tempstr = substr($str, $pos1, $long ); //on recup la valeur
//echo 'compteur ='. $vallignecpt.'<br>';
//on regarde si on a remplis le champ pour forcer la valeur
$tempforce = 'force'.$vallignecpt;
if (isset($_POST[$tempforce]) && $_POST[$tempforce] != ""){
$valligne [$vallignecpt] = trim($_POST[$tempforce]);
} else {
//sinon on remplis avec la valeur trouvée
$valligne [$vallignecpt] = $tempstr ;
}
$vallignecpt++;
//echo "<strong> valeur ajout?e=</strong>".$tempstr.'<br><br>';
$trouve=1;
$str = substr ($str, ($pos2+1));
//echo 'nouvelle Phrase='.$str.'<br>';
$nbcar = strlen($str);
}
}

}

}

//print_r ($valligne);
$tabcsv[$cpt] = $valligne;
$valligne = "";
$cpt ++;
//echo $str.'<br>';
}
}
fclose ($fp);
//print_r ($tabcsv);

//g?n?ration de la requette

$colones = "(" ;
for ($g=0; $g<$fields; $g++) {

$colones .=  '`'.$_POST["colone$g"].'`';
//pour ne pas ajouter de virgule apres la derniere colone on teste
if ($g < ($fields-1)){
$colones .= ", ";
}
}
$colones .= " ) ";
//echo '<br>colones = '.$colones;
//echo '<br> csv : ';
//echo $_POST['colonecsv0'];

echo $nb_colones_csv.' champs dans le fichier '.$name_file.'<br />';
echo $fields.' champs dans la table '.$table.'<br />';

//génération de la requette
$numligneval = 1;//compteur qui va donner le numero ? la ligne des valeurs ...pour ne pas avoir de trou dans l'index du tableau
//on incr?mente les lignes
for ($u=1; $u<=($cpt-1) ; $u++) {
// on verrifie que le parsage de la ligne soit bien fait en regardant que tabcsv contient bien le même nombre de champs pour cette ligne que le nombre de champs de la 1ere ligne du fichier csv
if (count($tabcsv[$u]) == $nb_colones_csv) {
$valeurs[$numligneval] = "(" ;
//on remplis les valeurs en fonction du nb de colones
for ($m=0; $m<$fields ; $m++) {

$tempcol = 'colonecsv'.$m;

//on stocke la valeur sans les espaces avant et après
// on evite d'afficher un erreur d'index indefini sur la table si on a pas choisi de correspondance de champ avec @
@$valeurs[$numligneval] .= '\''.trim($tabcsv[$u][$_POST[$tempcol]]).'\'';

//pour ne pas ajouter de virgule apres la derniere colone on teste

if ($m < ($fields-1)){
$valeurs[$numligneval] .= ", ";
}
}
$valeurs[$numligneval] .= " ) ";
$numligneval++;
} else {
//print_r ($tabcsv[$numligneval]);
//echo'<br>';
echo '<font color="red">Ligne '.($numligneval+1).' du fichier '.$name_file.' -> Erreur : '.count($tabcsv[$u]).' champs au lieu de '.$nb_colones_csv.' </font> - Ligne ignor?e. <br />';
//on remplis quand m?me le tableau des valeurs mais cette ligne sera ignor?e lors des insert ... ?a permet de garder le compteur des lignes ? jour au niveau du journal des erreurs sql
$valeurs[$numligneval] = "";
$numligneval++;
}

}

// FONCTIONS D'IMPORT DANS LA BDD
/* ?a n'est pas tout ? fait la m?me que dans mysql.php qui est en include
car celle ci affiche les erreurs sans couper le traitement en cas d'erreurs.
C'est celle l ? qu'on va donc utiliser */

function requette_avec_erreur($str_query, $connect=1)
{
if ($connect==1){connecter();} // si connect =1 on se connect
$resultat = mysql_query($str_query);
if ($connect==1){deconnecter();} // si connect =1 on se deconnect
if ($resultat)
{
return $resultat;
}
else
{
return 0;
//erreur(3); //si on veux renvoyer ? une action pr?cise en cas d'erreur
}
}
echo '<br /><strong>import en cours</strong> <br /><br />';
$erreur_sql = ""; //on initialise le journal des erreurs

//insert dans la base
echo 'La ligne 1 du fichier CSV correspond à la définition des champs. <br />';
connecter();
for ($u=1; $u<$numligneval; $u++) {
if ($valeurs[$u] != ""){
$req = "INSERT INTO $table $colones VALUES $valeurs[$u] ";
echo "<br>".$req.'<br />';

if (requette_avec_erreur($req,0)) {
echo 'ajout de la ligne '.($u+1).' du fichier '.$name_file.'.<br />';
} else {
$erreur_sql .= '<span style="color:red">Ligne '.($u+1).' du fichier '.$name_file.' -> Erreur SQL '.mysql_errno().' : '.mysql_error().'</span><br />';
echo '<font color="red">ligne '.($u+1).' -> Erreur SQL</font><br />';
}
}

}

deconnecter();
?>
<br /><strong>Fin de l'import</strong><br />
<strong> JOURNAL DES ERREURS SQL</strong><br />
<?php
if (!empty($erreur_sql))
{
echo $erreur_sql;
}
else
{
?>
Pas d'erreurs detectees lors de l'import
<?php
}
}
?>

</body>
</html>

Conclusion :


Voici donc ma contribution.
Code fonctionnel en date du 7/06/10

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

cs_LDDL
Messages postés
35
Date d'inscription
dimanche 27 avril 2003
Statut
Membre
Dernière intervention
7 mars 2013
-
Bonjour,
En regardant rapidement le code, la fonction http://dev.mysql.com/doc/refman/5.0/fr/load-data.html ne fait elle pas déja cela ?
cs_shannara
Messages postés
2
Date d'inscription
lundi 7 juin 2010
Statut
Membre
Dernière intervention
7 juin 2010
-
LDDL
avant de critiquer.
<citation>"En regardant RAPIDEMENT le code, ..."</citation>
Il y a une difference large entre "regarder RAPIDEMENT" et "lire attentivement".

Relis le code attentivement et tu comprendra.
une piste regarde le lien sur le script de caviar.

Amicalement
cs_caviar
Messages postés
329
Date d'inscription
samedi 4 janvier 2003
Statut
Membre
Dernière intervention
29 mars 2015
3 -
ah ben c'est une bonne chose d'avoir débuggé ce script !
ça fait très longtemps que je l'ai fait et j'ai toujours des questions auxquelles je ne pouvais plus répondre dessus !
excellent ! je vais tester ça !
++
nicov29280
Messages postés
2
Date d'inscription
samedi 21 janvier 2006
Statut
Membre
Dernière intervention
14 janvier 2011
-
Je rajoute ici ma question concernant la fonction requette pour le cas où ce sujet serait lu avant.
Il m'est impossible de la passer, est-ce que quelqu'un sait d'où cela provient ?
bigthulhu
Messages postés
3
Date d'inscription
jeudi 8 janvier 2009
Statut
Membre
Dernière intervention
26 janvier 2011
-
Chapeau mon ami ... 1000 merci.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.