exporter le resultat d'une requete en fichier csv

ptiloup21
Invité n'ayant pas de compte PHPfrance

13 févr. 2011, 21:25

bonjour, je debute et je rencontre des soucis, j'ai un site sur lequel, j'ai faite une interface. J'ai un bouton qui me sert a afficher les resultats de requetes. je voudrais faire en sorte d'avoir le même bouton, sauf que au lieu que ca s'affiche dans une page, je voudrais que ca me telecharge le resultat en csv ou format excel. A savoir que mon bouton actuel me genere une pages avec un tableau.

voici mon code :

...
...
case 'affpan':
$titre = $_POST[titre];
$ids = $_POST[ids];
$ids = explode (";", $ids );
$sql="SELECT * FROM publipostage where ID = '$ids[0]'";
for($i=1;$i < count($ids);$i++)
{
$sql.=" OR ID = '$ids[$i]' ";
}
echo "affichage des pannelistes de l'enquête : $titre<br />";
include "src/aff.php";
break;

...
...

<li class="form-line" id="id_2">
<div id="cid_2" class="form-input-wide">
<div style="margin-left:156px" class="form-buttons-wrapper">
<button id="input_2" type="submit" class="form-submit-button" name="envoi" value="affpan">
afficher les pannelistes
</button>
</div>
</div>
</li>

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

13 févr. 2011, 22:36

salut,

il va te falloir utiliser la fonction header pour forcer le téléchargement des données. http://www.php.net/header

Tu n'a pas besoin de créer réellement le fichier sur le disque pour cela.

@+
Il en faut peu pour être heureux ......

ViPHP
ViPHP | 1996 Messages

14 févr. 2011, 19:57

Sert toi aussi des caches ob_start(), ob_get_contents() et ob_end_flush(),... pour mettre en cache ce que tu veux ensuite afficher via les fonctions header.
It is nice to be important but it is more important to be nice
http://www.aureuswebfactory.fr

ViPHP
ViPHP | 5462 Messages

14 févr. 2011, 20:07

je te conseil d'utiliser un fichier temporaire pour créer ton CSV le couple tmpfile + fgetcsv c'est que du bonheur
pour ta requête pas besoin de t'embêter non plus a faire un boucle un simple IN va suffir (remplacer les ; par ,)
SELECT * FROM `publipostage` WHERE `id` IN(1, 25, 68, 64, 87)
tu peux ensuite créer le CSV très simplement comme ca :
$sql = "SELECT * FROM `test`";
 
$result = mysql_unbuffered_query($sql);
$handle = tmpfile();
$fields = mysql_fetch_assoc($result);
 
fputcsv($handle, array_keys($fields));
 
do
{
    fputcsv($handle, $fields);
}
while($fields = mysql_fetch_assoc($result));
 
mysql_free_result($result);
 
//les headers à mettre ici
rewind($handle);
fpassthru($handle);
fclose($handle);
exit;

ptiloup21
Invité n'ayant pas de compte PHPfrance

14 févr. 2011, 23:37

Merci a tous, je comprend pas tout ce que vous me dite mais bon, je vais essayer, sinon, si je fourni le fichier complet, est-ce que quelqu'un, peut me faire les modifs et m'expliquer ?

Merci d'avance a tous.

ViPHP
AB
ViPHP | 5818 Messages

15 févr. 2011, 01:23

Commençons par le début.

stealth35 t'a donné le résultat de ce que tu devrais obtenir pour éviter la boucle inutile qui construit ta requête.
SELECT * FROM `publipostage` WHERE `id` IN(1, 25, 68, 64, 87)
(les chiffres à l'intérieur du IN étant tes ID)

Dans ton code tu écris
$ids = explode (";", $ids );
Si à la place tu fais
$ids = implode (",", $ids );
echo $ids;
ça donne quoi ? ça ressemble pas un peu à ce qu'on peut mettre dans la clause IN de la requête indiquée plus haut ?

Réécris le code que tu nous à montré en suivant ces conseils ensuite on ira plus loin.

Cela dit pour la suite stealth35 t'a mâché le travail.

Juste dans son code, avant les headers tu auras peut-être besoin de faire
$info = stream_get_meta_data($handle);
$filesize = filesize($info['uri']);
(si tu veux passer la taille du fichier en téléchargement)

ViPHP
AB
ViPHP | 5818 Messages

15 févr. 2011, 01:40

Au passage, toujours à propos du code de stealth35, pour ceux qui voudraient utiliser l'extension mysqli, il n'existe pas de fonction mysqli_unbuffered_query.
C'est dans le troisième paramètre (en mode procédural) de mysqli_query que l'on indique MYSQLI_USE_RESULT pour avoir le même comportement. Cela dit cette technique de ne pas stocker les résultats n'est nécessaire (ou recommandée) que pour un gros volume de requête (ie, y'aurait quelques désavantages à l'utiliser systématiquement, cf la doc).

ptiloup21
Invité n'ayant pas de compte PHPfrance

15 févr. 2011, 10:26

Si ca derange pas, je prefere, fournir le fichier (13ko) possibilite par mail si vous voulez ou sinon dite moi.

herve29
Invité n'ayant pas de compte PHPfrance

15 févr. 2011, 10:54

Bonjour,
Je me permet de participer à ce post car , j'ai à traiter un besoin similaire. et je ne suis pas un expert en php

Merci pour le petit bout de code de stealh35, qui m'a fait gagner du temps.

J'arrive bien à créer le fichier csv sur le serveur,
mais j'aimerais plutôt avoir un bouton qui me donne une invite de type "enregister sous...", pour que le fichier soit enregistré sur le PC de l'utilisateur.

Je pense que c'est possible, peut être en passant par javascript? J'imagine qu'il existe une fonction pour ça?

En tout cas, merci d'avance pour vos suggestions.

PTILOUP21
Invité n'ayant pas de compte PHPfrance

15 févr. 2011, 17:31

Si ca dérange pas, je préfère, fournir le fichier (13ko) possibilité par mail si vous voulez ou sinon dite moi.
je rajoute a mon précédant message : Moi aussi, il faut que ca m'ouvre une fenêtre enregistrer sous. Mais je n'arrive déjà pas a modifier ma page pour faire la création du csv.

ViPHP
xTG
ViPHP | 7331 Messages

15 févr. 2011, 17:36

La fonction header() de PHP suffit pour forcer un téléchargement.
Une base ici : http://www.apprendre-php.com/tutoriels/ ... chier.html
A améliorer cependant, car leur code ne vérifie en rien le fichier. ;)

ViPHP
AB
ViPHP | 5818 Messages

15 févr. 2011, 18:37

Si ca derange pas, je prefere, fournir le fichier (13ko) possibilite par mail si vous voulez ou sinon dite moi.
Non on veut pas tout ton code, juste celui qui nous intéresse pour ton problème c'est à dire faire la requête, mettre tes enregistrements sous forme d'un fichier csv puis proposer celui-ci en téléchargement, soit le premier code que tu nous a donné mais adapté avec les conseils ci-dessus. Et on règle les problèmes sur le forum pour que tout le monde en profite :)

Bon donc pour proposer le fichier temporaire en téléchargement, il faut rajouter quelques lignes de code en lieu et place du commentaire "//les headers à mettre ici" Voici donc ces headers (pour plus d'info voir le lien donné par xTG) et le moyen de récupérer la taille du fichier :
//...
$info = stream_get_meta_data($handle);

$filesize = filesize($info['uri']);

$nom_du_fichier = 'monfichier'; //à définir

// Entêtes pour forcer le téléchargement, type de fichier, poids, disposition
header('Content-Type: application/octet-stream');	
header("Content-Transfer-Encoding: text/csv");
header("Content-Length: ".$filesize);
header("Content-Disposition: attachment; filename=\"".$nom_du_fichier."\"");

// Différents code pour ne pas mettre le fichier dans le cache du navigateur
header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, public");
header("Pragma: no-cache"); 
header("Expires: 0"); 

//Remise à zéro, envoi du fichier, puis effacement, puis sortie du script.
rewind($handle);
fpassthru($handle);
fclose($handle);
exit;
@PTILOUP21 alors tu l'a fait le début du code (la requête) ?
Que donne echo $ids; comme je disais plus haut ? Montres nous ce que tu as fait.

herve29
Invité n'ayant pas de compte PHPfrance

16 févr. 2011, 09:50

L'instruction header fonctionne bien et fait exactement ce que je veut.
Merci pour vos informations précieuses.

ptiloup21
Invité n'ayant pas de compte PHPfrance

19 févr. 2011, 00:07

Pour l'instant, j'ai essayer de mettre ce que vous m'avez dit, mais je comprend pas comment cela fonctionne, ou je doit mettre les header ... et ca fonctionne pas car je pense que je ne fait pas comme il faudrait faire. je vais essayer de me pencher dessus dimanche et je reviens vers vous.

ViPHP
AB
ViPHP | 5818 Messages

19 févr. 2011, 03:52

Pour l'instant, j'ai essayer de mettre ce que vous m'avez dit, mais je comprend pas comment cela fonctionne, ou je doit mettre les header ... et ca fonctionne pas car je pense que je ne fait pas comme il faudrait faire. je vais essayer de me pencher dessus dimanche et je reviens vers vous.
Ok et montres nous ce que tu as fait :)