217 votes

Comment puis-je générer un CSV UTF-8 en PHP qu'Excel lira correctement ?

J'ai ce truc très simple qui sort des trucs au format CSV, mais il faut que ce soit en UTF-8. J'ouvre ce fichier dans TextEdit ou TextMate ou Dreamweaver et il affiche correctement les caractères UTF-8, mais si je l'ouvre dans Excel, il fait ce genre de chose stupide íÄ à la place. Voici ce que j'ai en tête de mon document :

header("content-type:application/csv;charset=UTF-8");
header("Content-Disposition:attachment;filename=\"CHS.csv\"");

Tout cela semble avoir l'effet désiré, mais Excel (Mac, 2008) ne veut pas l'importer correctement. Il n'y a pas d'option dans Excel qui me permette d'ouvrir le fichier en UTF-8 ou quoi que ce soit d'autre, alors je suis un peu ennuyé.

Je n'arrive pas à trouver de solution claire à ce problème, bien que de nombreuses personnes aient le même problème. La chose que je vois le plus souvent est d'inclure la nomenclature, mais je n'arrive pas à savoir exactement comment faire. Comme vous pouvez le voir ci-dessus, je suis juste echo Je n'écris pas de fichier. Je peux le faire si j'en ai besoin, mais je ne le fais pas parce que cela ne semble pas nécessaire pour le moment. Vous pouvez m'aider ?

Mise à jour : j'ai essayé d'envoyer la nomenclature en tant que echo pack("CCC", 0xef, 0xbb, 0xbf); que je viens de tirer d'un site qui essayait de détecter la nomenclature. Mais Excel se contente d'ajouter ces trois caractères à la toute première cellule lors de l'importation, ce qui perturbe encore les caractères spéciaux.

2 votes

Excel ne fournit pas d'option pour ajuster le jeu de caractères du fichier entrant ? Êtes-vous sûr à 100% de cela ? Je n'ai pas de copie à portée de main et je ne peux donc pas faire d'essai, mais j'imagine qu'il existe une option de réglage du jeu de caractères. doit être une boîte déroulante quelque part.

0 votes

Il s'agit d'Excel sur un Mac - il semble plus limité qu'Excel sur le PC. Il n'y a pas du tout de liste déroulante dans la boîte de dialogue Ouvrir, au-delà des types de fichiers à ouvrir. J'ai cherché partout. Si c'est là, c'est obscur. Je dirais que c'est sûr à 98%.

0 votes

Microsoft office ou openoffice ?

329voto

Daniel Magliola Points 8347

J'ai le même problème (ou un problème similaire).

Dans mon cas, si j'ajoute une nomenclature à la sortie, cela fonctionne :

header('Content-Encoding: UTF-8');
header('Content-type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename=Customers_Export.csv');
echo "\xEF\xBB\xBF"; // UTF-8 BOM

Je crois que c'est un hack assez laid, mais il a fonctionné pour moi, au moins pour Excel 2007 Windows. Je ne suis pas sûr que cela fonctionne sur Mac.

14 votes

Moche, mais super utile. Merci.

7 votes

Je suis presque sûr que cela ne fonctionne pas du tout sous OS X, malheureusement. Je pense qu'il est possible d'afficher la nomenclature lors de l'importation (attention : souvenirs flous).

2 votes

C'est exact. En tout cas, j'ai essayé de faire précéder d'une nomenclature, comme dans l'exemple ci-dessus, mais cela n'a fait qu'afficher des caractères bizarres au début et a continué à afficher les caractères spéciaux de manière incorrecte (testé dans Excel 2011). Cela semble fonctionner au mieux pour moi dans tous les paramètres : stackoverflow.com/a/1648671/1005334 (en utilisant PHP).

148voto

timgws Points 1437

Je cite un ingénieur support Microsoft ,

Excel pour Mac ne supporte pas actuellement UTF-8

Mise à jour, 2017 : Ceci est vrai pour toutes les versions de Microsoft Excel pour Mac avant Office 2016 . Les versions plus récentes (à partir d'Office 365) prennent désormais en charge UTF-8.

Afin de produire un contenu UTF-8 qu'Excel, tant sous Windows que sous OS X, sera en mesure de lire avec succès, vous devrez faire deux choses :

  1. Assurez-vous de convertir votre texte CSV UTF-8 en UTF-16LE.

    mb_convert_encoding($csv, 'UTF-16LE', 'UTF-8');
  2. Assurez-vous que vous ajoutez le Marque d'ordre des octets UTF-16LE au début du fichier

    chr(255) . chr(254)

Le problème suivant qui n'apparaît qu'avec Excel sous OS X (mais no Windows) sera lors de l'affichage d'un fichier CSV avec des valeurs séparées par des virgules, Excel ne rendra que les lignes avec une seule ligne et tout le texte avec les virgules dans la première ligne.

Le moyen d'éviter cela est d'utiliser des tabulations comme valeur séparée.

J'ai utilisé cette fonction à partir des commentaires PHP (en utilisant les onglets " \t " au lieu de virgules) et cela a fonctionné parfaitement sur OS X et Windows Excel.

Notez que pour résoudre un problème avec une colonne vide à la fin d'une ligne, j'ai dû modifier la ligne de code qui dit :

    $field_cnt = count($fields);

à

    $field_cnt = count($fields)-1;

Comme le disent certains des autres commentaires sur cette page, d'autres tableurs comme OpenOffice Calc, Numbers d'Apple et Spreadsheet de Google Doc n'ont aucun problème avec les fichiers UTF-8 comportant des virgules.

Ver le tableau dans cette question pour savoir ce qui fonctionne et ce qui ne fonctionne pas pour les fichiers CSV Unicode dans Excel.


En passant, je pourrais ajouter que si vous utilisez Compositeur vous devriez envisager d'ajouter League\Csv à vos besoins. League\Csv a une très belle API pour la création de fichiers CSV .

Pour utiliser League\Csv avec cette méthode de création de fichiers CSV, consultez la rubrique cet exemple

2 votes

Traitez-moi d'idiot, mais je n'arrive pas à faire fonctionner ce système. J'ai converti mes données à l'aide de la fonction mb_convert_encoding et j'ai sorti la nomenclature avant le contenu du fichier, mais je n'obtiens qu'une seule ligne de caractères chinois lorsque j'ouvre le fichier dans Excel. J'utilise toujours des virgules plutôt que des tabulations pour l'instant, mais je suppose que cela ne devrait pas provoquer ce que je vois.

0 votes

@JohnRix c'est étrange. Ce code a littéralement résolu tous les problèmes que j'ai rencontrés avec l'exportation de fichiers CSV - à l'exception des importateurs qui n'acceptent que les virgules. Pouvez-vous m'envoyer un pastebin du code que vous utilisez, avec un tableau que vous transformez en CSV et une copie du fichier exporté ?

2 votes

Cette solution a également résolu le problème UTF8 pour moi sur Mac et Windows. J'ai également constaté que l'ajout d'une ligne avec sep=; o sep=, au fichier CSV indique à Excel comment le CSV est séparé et les colonnes seront à nouveau créées correctement.

36voto

Jazzer Points 216

Voici comment j'ai procédé (c'est pour demander au navigateur de télécharger le fichier csv) :

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=file.csv');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
echo "\xEF\xBB\xBF"; // UTF-8 BOM
echo $csv_file_content;
exit();

La seule chose qu'il a corrigé est le problème d'encodage UTF8 dans l'aperçu du CSV lorsque vous appuyez sur la barre d'espace sur Mac... mais pas dans Excel Mac 2008... je ne sais pas pourquoi...

1 votes

La ligne de code de la nomenclature UTF-8 a sauvé ma journée avec l'exportation vers le format xls.

9 votes

Je cherchais un moyen de sortir directement sur le navigateur en utf8, quand je suis tombé sur ce post, Voici ma solution avec des crédits à ce post pour le BOM et le binary transfer header. $outstream = fopen( "php://output", 'w' ); fputs( $outstream, "\xEF\xBB\xBF" ); foreach ( $export as $fields ) { fputcsv( $outstream, $fields ); } fclose( $outstream );

0 votes

Typo - enlever le double )) .

23voto

Jasdeep Gosal Points 356

Je viens de traiter le même problème, et j'ai trouvé deux solutions.

  1. Utilisez le PHPExcel classe comme suggéré par bpeterson76 .

    • En utilisant cette classe qui génère le fichier le plus largement compatible, j'ai pu générer un fichier à partir de données encodées en UTF-8 qui s'est ouvert sans problème dans Excel 2008 Mac, Excel 2007 Windows, et Google Docs.
    • Le plus gros problème de l'utilisation de PHPExcel est qu'il est lent et consomme beaucoup de mémoire, ce qui n'est pas un problème pour les fichiers de taille raisonnable, mais si votre fichier Excel/CSV comporte des centaines ou des milliers de lignes, cette bibliothèque devient inutilisable .
    • Voici une méthode PHP qui va prendre des données TSV et sortir un fichier Excel vers le navigateur, notez qu'elle utilise le Writer Excel5, ce qui signifie que le fichier devrait être compatible avec les anciennes versions d'Excel, mais je n'y ai plus accès, donc je ne peux pas les tester.

      function excel_export($tsv_data, $filename) {
          $export_data = preg_split("/\n/", $tsv_data);
          foreach($export_data as &$row) {
              $row = preg_split("/\t/", $row);
          }
      
          include("includes/PHPExcel.php");
          include('includes/PHPExcel/Writer/Excel5.php');
      
          $objPHPExcel = new PHPExcel();          
      
          $objPHPExcel->setActiveSheetIndex(0);
          $sheet = $objPHPExcel->getActiveSheet();
          $row = '1';
          $col = "A";
          foreach($export_data as $row_cells) {
              if(!is_array($row_cells)) { continue; }
                  foreach($row_cells as $cell) {
                      $sheet->setCellValue($col.$row, $cell);
                      $col++;
                  }
              $row += 1;
              $col = "A";
          }
      
          $objWriter = new PHPExcel_Writer_Excel5($objPHPExcel);
          header('Content-Type: application/vnd.ms-excel');
          header('Content-Disposition: attachment;filename="'.$filename.'.xls"');
          header('Cache-Control: max-age=0');
          $objWriter->save('php://output');   
          exit;   
      }
  2. En raison des problèmes d'efficacité de PHPExcel, j'ai également dû trouver un moyen de générer un fichier CSV ou TSV compatible avec UTF-8 et Excel.

    • Le mieux que j'ai pu obtenir est un fichier compatible avec Excel 2008 Mac, et Excel 2007 PC, mais pas avec Google Docs, ce qui est suffisant pour mon application.
    • J'ai trouvé la solution aquí en particulier, cette réponse mais vous devriez également lire le réponse acceptée car il explique le problème.
    • Voici le code PHP que j'ai utilisé, notez que j'utilise des données tsv (tabulations comme délimiteurs au lieu de virgules) :

      header ( 'HTTP/1.1 200 OK' );
      header ( 'Date: ' . date ( 'D M j G:i:s T Y' ) );
      header ( 'Last-Modified: ' . date ( 'D M j G:i:s T Y' ) );
      header ( 'Content-Type: application/vnd.ms-excel') ;
      header ( 'Content-Disposition: attachment;filename=export.csv' );
      print chr(255) . chr(254) . mb_convert_encoding($tsv_data, 'UTF-16LE', 'UTF-8');
      exit;

0 votes

Je rencontre le même problème sur Windows-7 Excel 2007 et j'ai essayé toutes les suggestions mais sans succès :(

0 votes

La solution UTF-16LE est celle qui a fonctionné. Notez que vous devez formater le tsv correctement, et qu'il doit être tsc, c'est-à-dire délimité par des tabulations, et non par des virgules. Voir aussi le post de Marc ici : stackoverflow.com/a/1648671/1697370

13voto

suanik Points 81

Excel ne supporte pas l'UTF-8. Vous devez encoder votre texte UTF-8 en UCS-2LE.

mb_convert_encoding($output, 'UCS-2LE', 'UTF-8');

3 votes

Mieux vaut utiliser l'UTF-16LE comme suggéré ci-dessus, qui couvre tous les caractères existants.

0 votes

J'ai remarqué que ce mb_convert_encoding fonctionne bien et affiche correctement les diacritiques dans mon fichier XLS exporté. J'ai les configurations par défaut de mysql et apache + php configurés pour travailler avec utf-8.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X