J'essaie de convertir un tableau de produits en un fichier CSV, mais cela ne semble pas se dérouler comme prévu. Le fichier CSV est une longue ligne, voici mon code:
for($i=0;$i<count($prods);$i++) {
$sql = "SELECT * FROM products WHERE id = '".$prods[$i]."'";
$result = $mysqli->query($sql);
$info = $result->fetch_array();
}
$header = '';
for($i=0;$i<count($info);$i++)
{
$row = $info[$i];
$line = '';
for($b=0;$b<count($row);$b++)
{
$value = $row[$b];
if ( ( !isset( $value ) ) || ( $value == "" ) )
{
$value = "\t";
}
else
{
$value = str_replace( '"' , '""' , $value );
$value = '"' . $value . '"' . "\t";
}
$line .= $value;
}
$data .= trim( $line ) . "\n";
}
$data = str_replace( "\r" , "" , $data );
if ( $data == "" )
{
$data = "\n(0) Records Found!\n";
}
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=your_desired_name.xls");
header("Pragma: no-cache");
header("Expires: 0");
array_to_CSV($data);
function array_to_CSV($data)
{
$outstream = fopen("php://output", 'r+');
fputcsv($outstream, $data, ',', '"');
rewind($outstream);
$csv = fgets($outstream);
fclose($outstream);
return $csv;
}
En outre, l'en-tête ne force pas le téléchargement. J'ai copié et collé la sortie, puis enregistré au format .csv
PROBLÈME RÉSOLU:
Si quelqu'un d'autre cherchait la même chose, trouva une meilleure façon de le faire:
$num = 0;
$sql = "SELECT id, name, description FROM products";
if($result = $mysqli->query($sql)) {
while($p = $result->fetch_array()) {
$prod[$num]['id'] = $p['id'];
$prod[$num]['name'] = $p['name'];
$prod[$num]['description'] = $p['description'];
$num++;
}
}
$output = fopen("php://output",'w') or die("Can't open php://output");
header("Content-Type:application/csv");
header("Content-Disposition:attachment;filename=pressurecsv.csv");
fputcsv($output, array('id','name','description'));
foreach($prod as $product) {
fputcsv($output, $product);
}
fclose($output) or die("Can't close php://output");
Au lieu d’écrire des valeurs, envisagez d’utiliser fputcsv()
.
Cela peut résoudre votre problème immédiatement.
Essayez d'utiliser;
PHP_EOL
Pour terminer chaque nouvelle ligne dans votre sortie CSV.
Je suppose que le texte est délimitant, mais ne passe-t-il pas à la rangée suivante?
C'est une constante PHP. Cela déterminera la bonne fin de ligne dont vous avez besoin.
Windows, par exemple, utilise "\ r\n". Je me suis creusé la tête avec celui-là alors que ma sortie ne dépassait pas une nouvelle ligne.
Je sais que c’est vieux, j’avais un cas dans lequel j’avais besoin que la clé de tableau fût également incluse dans le fichier CSV, aussi j’ai mis à jour le script de Jesse Q pour le faire . t ajouter une nouvelle ligne (la nouvelle ligne est quelque chose que j’ai ajouté et qui devrait vraiment être là).
Veuillez noter que cela ne fonctionne qu'avec des tableaux à valeur unique (key, value)
. mais pourrait facilement être mis à jour pour gérer (key, array())
multi-dimensionnelle.
function arrayToCsv( array &$fields, $delimiter = ',', $Enclosure = '"', $encloseAll = false, $nullToMysqlNull = false ) {
$delimiter_esc = preg_quote($delimiter, '/');
$Enclosure_esc = preg_quote($Enclosure, '/');
$output = '';
foreach ( $fields as $key => $field ) {
if ($field === null && $nullToMysqlNull) {
$output = '';
continue;
}
// Enclose fields containing $delimiter, $Enclosure or whitespace
if ( $encloseAll || preg_match( "/(?:${delimiter_esc}|${Enclosure_esc}|\s)/", $field ) ) {
$output .= $key;
$output .= $delimiter;
$output .= $Enclosure . str_replace($Enclosure, $Enclosure . $Enclosure, $field) . $Enclosure;
$output .= PHP_EOL;
}
else {
$output .= $key;
$output .= $delimiter;
$output .= $field;
$output .= PHP_EOL;
}
}
return $output ;
}
Dans mon cas, mon tableau était multidimensionnel, potentiellement avec des tableaux comme valeurs. J'ai donc créé cette fonction récursive pour détruire complètement le tableau:
function array2csv($array, &$title, &$data) {
foreach($array as $key => $value) {
if(is_array($value)) {
$title .= $key . ",";
$data .= "" . ",";
array2csv($value, $title, $data);
} else {
$title .= $key . ",";
$data .= '"' . $value . '",';
}
}
}
Comme les différents niveaux de mon tableau ne se prêtaient pas bien au format CSV plat, j'ai créé une colonne vierge avec la clé du sous-tableau pour servir d'introduction descriptive au niveau de données suivant. Exemple de sortie:
agentid fname lname empid totals sales leads dish dishnet top200_plus top120 latino base_packages
G-adriana ADRIANA EUGENIA PALOMO PAIZ 886 0 19 0 0 0 0 0
Vous pouvez facilement supprimer cette colonne "intro" (descriptive), mais dans mon cas, j'avais des en-têtes de colonne répétitifs, à savoir inbound_leads, dans chaque sous-tableau, ce qui m'a donné une rupture/un titre précédant la section suivante. Retirer:
$title .= $key . ",";
$data .= "" . ",";
après le is_array () pour compacter le code et supprimer la colonne supplémentaire.
Puisque je voulais à la fois une ligne de titre et une ligne de données, je passe deux variables à la fonction et, une fois l'appel de la fonction terminé, je termine les deux avec PHP_EOL:
$title .= PHP_EOL;
$data .= PHP_EOL;
Oui, je sais que je laisse une virgule supplémentaire, mais par souci de brièveté, je ne l'ai pas manipulée ici.
Les tableaux de données sont convertis au format csv 'text/csv' par la fonction php intégrée fputcsv prend en charge les virgules, les guillemets, etc.
Regarder
https://coderwall.com/p/zvzwwa/array-to-comma-separated-string-in-php
http://www.php.net/manual/en/function.fputcsv.php
C'est une solution simple qui exporte un tableau en chaîne csv:
function array2csv($data, $delimiter = ',', $Enclosure = '"', $escape_char = "\\")
{
$f = fopen('php://memory', 'r+');
foreach ($data as $item) {
fputcsv($f, $item, $delimiter, $Enclosure, $escape_char);
}
rewind($f);
return stream_get_contents($f);
}
$list = array (
array('aaa', 'bbb', 'ccc', 'dddd'),
array('123', '456', '789'),
array('"aaa"', '"bbb"')
);
var_dump(array2csv($list));