Question

J'ai cette chose très simple qui produit juste des choses au format CSV, mais il faut que ce soit UTF-8. J'ouvre ce fichier dans TextEdit ou TextMate ou Dreamweaver et il affiche caractères UTF-8 correctement, mais si je l'ouvre dans Excel, il fait cela idiot iA genre de chose à la place. Voici ce que j'ai à la tête de mon document:

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

Cela semble tout avoir l'effet désiré, sauf Excel (Mac, 2008) ne veut pas importer correctement. Il n'y a pas d'options dans Excel pour moi « ouverte en UTF-8 » ou quoi que ce soit, alors ... Je suis un peu agacé.

Je ne peux pas sembler trouver des solutions claires à ce partout, malgré un grand nombre de personnes ayant le même problème. La chose que je vois le plus est d'inclure la nomenclature, mais je ne peux pas comprendre exactement comment faire. Comme vous pouvez le voir ci-dessus, je suis juste echoing ces données, je ne suis pas d'écrire un fichier. Je peux le faire si je dois, je ne suis pas parce qu'il ne semble pas comme un besoin à ce stade. Toute aide?

Mise à jour: J'ai essayé faisant écho à la nomenclature comme echo pack("CCC", 0xef, 0xbb, 0xbf); que je viens de tirer sur un site qui a essayé de détecter la nomenclature. Mais Excel ajoute que ces trois personnages à la première cellule lors de l'importation, et encore bousille les caractères spéciaux.

Était-ce utile?

La solution

Pour citer un ingénieur de support Microsoft ,

  

Excel pour Mac ne prend pas en charge UTF-8

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

Pour la sortie du contenu UTF-8 que Excel à la fois sous Windows et OS X sera en mesure de lire avec succès, vous devez faire deux choses:

  1. Assurez-vous que vous convertissez votre texte UTF-8 en UTF-16LE

    mb_convert_encoding($csv, 'UTF-16LE', 'UTF-8');
    
  2. Assurez-vous que vous ajoutez la marque d'ordre d'octets UTF-16LE

    chr(255) . chr(254)
    

Le problème suivant qui apparaît uniquement avec Excel sur OS X (mais pas Windows) sera lors de l'affichage d'un fichier CSV séparés par des virgules valeurs, Excel rend uniquement les lignes avec une ligne et tous les texte ainsi que les virgules dans la première rangée.

La façon d'éviter cela est d'utiliser les onglets comme valeur séparée.

cette fonction des commentaires de 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 comme la fin d'une ligne, que je ne dois changer la ligne de code qui dit:

    $field_cnt = count($fields);

à

    $field_cnt = count($fields)-1;

Comme certains des autres commentaires sur cette page par exemple, d'autres applications de tableur comme OpenOffice Calc, propres numéros d'Apple et de la feuille de calcul Google Doc ont aucun problème avec les fichiers UTF-8 par des virgules.

Voir la table dans cette question pour ce qui fonctionne et ne fonctionne pas pour les fichiers Unicode CSV dans Excel


Comme une note de côté, je pourrais ajouter que si vous utilisez Composer, vous devriez jeter un oeil à ajouter League\Csv à votre exige. League\Csv a une API très agréable pour la construction de fichiers CSV .

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

Autres conseils

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

Dans mon cas, si j'ajoute une nomenclature à la sortie, il 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 travaillé pour moi, au moins pour Excel 2007 de Windows. Pas sûr que ça va marcher sur Mac.

Voici comment je l'ai fait (c'est au navigateur invite à 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 fixe UTF8 problème encodage en aperçu CSV lorsque vous appuyez sur la barre d'espace sur Mac .. mais pas dans Excel Mac 2008 ... ne sais pas pourquoi

Je viens de traiter le même problème, et est venu avec deux solutions.

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

    • L'utilisation de cette classe génère le fichier le plus largement compatible, je suis en mesure de générer un fichier de données UTF-8 codé qui a ouvert fin 2008 dans Excel Mac, Excel 2007 Windows et Google Docs.
    • Le plus gros problème avec l'utilisation PHPExcel est qu'il est lent et utilise beaucoup de mémoire, ce qui est un problème pour les fichiers de taille raisonnable, mais si votre fichier Excel / CSV a des centaines ou des milliers de lignes, cette bibliothèque devient inutilisable .
    • Voici une méthode PHP qui prendra des données TSV et la sortie d'un fichier Excel dans le navigateur, notez qu'il utilise l'écrivain Excel5, ce qui signifie que le fichier doit être compatible avec les anciennes versions d'Excel, mais je ne ont plus accès à tout, 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é avec PHPExcel, je devais aussi savoir comment générer un fichier CSV ou TSV compatible UTF-8 et Excel.

    • Le mieux que je pouvais trouver était un fichier compatible avec Excel 2008 Mac et Excel 2007 PC, mais pas Google Docs, ce qui est assez bon pour ma demande.
    • J'ai trouvé la solution , en particulier, cette réponse, mais vous devriez aussi lire le accepted répondre car il explique le problème.
    • Voici le code PHP je, notez que j'utilise TSV données (onglets 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;
      

Je faisais la même question et il a été résolu comme ci-dessous:

    header('Content-Encoding: UTF-8');
    header('Content-Type: text/csv; charset=utf-8' );
    header(sprintf( 'Content-Disposition: attachment; filename=my-csv-%s.csv', date( 'dmY-His' ) ) );
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');

    $df = fopen( 'php://output', 'w' );

    //This line is important:
    fputs( $df, "\xEF\xBB\xBF" ); // UTF-8 BOM !!!!!

    foreach ( $rows as $row ) {
        fputcsv( $df, $row );
    }
    fclose($df);
    exit();

Excel ne prend pas en charge UTF-8. Vous devez encoder votre texte UTF-8 dans UCS-2LE.

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

Pour donner suite à ceci:

Il semble que le problème est tout simplement avec Excel sur le Mac. Ce n'est pas comment je générer les fichiers, parce que même la génération CSVs à partir d'Excel est de les casser. Je sauverai CSV, et réimportation, et tous les personnages sont foiré.

... il ne semble pas être une bonne réponse à cette question. Merci pour toutes les suggestions.

Je dirais que de tout ce que j'ai lu, la suggestion de Magliola de la @ Daniel nomenclature serait probablement la meilleure solution pour un autre ordinateur. Mais il ne résout pas mon problème.

Dans mon cas, suite à des travaux très agréable pour faire fichier CSV avec UTF-8 caractères affichés correctement dans Excel.

$out = fopen('php://output', 'w');
fprintf($out, chr(0xEF).chr(0xBB).chr(0xBF));
fputcsv($out, $some_csv_strings);

L'en-tête de nomenclature 0xEF 0xBB 0xBF permettra Excel connaître l'encodage correct.

Cela fonctionne bien dans Excel pour Windows et Mac OS aussi.

Réparer les problèmes dans Excel qui ne sont pas des caractères affichés contenant diacritiques, des lettres cyrilliques, lettre grecque et les symboles monétaires.

function writeCSV($filename, $headings, $data) {   

    //Use tab as field separator
    $newTab  = "\t";
    $newLine  = "\n";

    $fputcsv  =  count($headings) ? '"'. implode('"'.$newTab.'"', $headings).'"'.$newLine : '';

    // Loop over the * to export
    if (! empty($data)) {
      foreach($data as $item) {
        $fputcsv .= '"'. implode('"'.$newTab.'"', $item).'"'.$newLine;
      }
    }

    //Convert CSV to UTF-16
    $encoded_csv = mb_convert_encoding($fputcsv, 'UTF-16LE', 'UTF-8');

    // Output CSV-specific headers
    header('Set-Cookie: fileDownload=true; path=/'); //This cookie is needed in order to trigger the success window.
    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: private",false);
    header("Content-Type: application/octet-stream");
    header("Content-Disposition: attachment; filename=\"$filename.csv\";" );
    header("Content-Transfer-Encoding: binary");
    header('Content-Length: '. strlen($encoded_csv));
    echo chr(255) . chr(254) . $encoded_csv; //php array convert to csv/excel

    exit;
}

Le fichier CSV musst inclure un Byte Order Mark.

Ou comme l'a suggéré et contourner l'écho juste avec le corps HTTP

Depuis UTF8 ne joue pas bien avec Excel. Vous pouvez convertir les données à un autre type de codage utilisant iconv().

par exemple.

iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $value),

Ajouter:

fprintf($file, chr(0xEF).chr(0xBB).chr(0xBF));

Ou:

fprintf($file, "\xEF\xBB\xBF");

Avant d'écrire tout contenu dans un fichier CSV.

Exemple:

<?php
$file = fopen( "file.csv", "w");
fprintf( $file, "\xEF\xBB\xBF");
fputcsv( $file, ["english", 122, "বাংলা"]);
fclose($file);

Conversion déjà utf-8 texte codé à l'aide mb_convert_encoding n'est pas nécessaire. Il suffit d'ajouter trois personnages devant le contenu original:

$newContent = chr(239) . chr(187) . chr(191) . $originalContent

Pour moi, ce a résolu le problème des caractères spéciaux dans les fichiers csv.

Comme je l'ai étudié et je trouve que UTF-8 ne fonctionne pas bien sur MAC et Windows donc j'ai essayé avec Windows 1252, il prend en charge bien sur les deux, mais vous devez sélectionner le type de codage sur ubuntu. Voici mon code$valueToWrite = mb_convert_encoding($value, 'Windows-1252');

$response->headers->set('Content-Type', $mime . '; charset=Windows-1252');
    $response->headers->set('Pragma', 'public');
    $response->headers->set('Content-Endcoding','Windows-1252');
    $response->headers->set('Cache-Control', 'maxage=1');
    $response->headers->set('Content-Disposition', $dispositionHeader);
    echo "\xEF\xBB\xBF"; // UTF-8 BOM
**This is 100% works fine in excel for both Windows7,8,10 and also All Mac OS.**
//Fix issues in excel that are not displaying characters containing diacritics, cyrillic letters, Greek letter and currency symbols.

function generateCSVFile($filename, $headings, $data) {

    //Use tab as field separator
    $newTab  = "\t";
    $newLine  = "\n";

    $fputcsv  =  count($headings) ? '"'. implode('"'.$newTab.'"', $headings).'"'.$newLine : '';

    // Loop over the * to export
    if (! empty($data)) {
      foreach($data as $item) {
        $fputcsv .= '"'. implode('"'.$newTab.'"', $item).'"'.$newLine;
      }
    }

    //Convert CSV to UTF-16
    $encoded_csv = mb_convert_encoding($fputcsv, 'UTF-16LE', 'UTF-8');

    // Output CSV-specific headers
    header('Set-Cookie: fileDownload=true; path=/'); //This cookie is needed in order to trigger the success window.
    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: private",false);
    header("Content-Type: application/octet-stream");
    header("Content-Disposition: attachment; filename=\"$filename.csv\";" );
    header("Content-Transfer-Encoding: binary");
    header('Content-Length: '. strlen($encoded_csv));
    echo chr(255) . chr(254) . $encoded_csv; //php array convert to csv/excel
    exit;
}

Que diriez-vous juste sortie pour Excel lui-même? Ceci est une excellente de classe qui vous permet de générer des fichiers XLS côté serveur. Je l'utilise souvent pour les clients qui ne peuvent pas « figure out » de csv et jusqu'à présent, n'a jamais eu une plainte. Il permet également une mise en forme supplémentaire (ombrage, RowHeights, calculs, etc.) que csv ne jamais faire.

vous pouvez convertir votre chaîne CSV avec iconv .  par exemple:

$csvString = "Möckmühl;in Möckmühl ist die Hölle los\n";
file_put_contents('path/newTest.csv',iconv("UTF-8", "ISO-8859-1//TRANSLIT",$csvString) );

Vous devez utiliser le codage « Windows 1252 ».

header('Content-Encoding: Windows-1252');
header('Content-type: text/csv; charset=Windows-1252');
header("Content-Disposition: attachment; filename={$filename}");

Peut-être que vous devez convertir vos chaînes:

private function convertToWindowsCharset($string) {
  $encoding = mb_detect_encoding($string);

  return iconv($encoding, "Windows-1252", $string);
}

Vous pouvez ajouter les 3 octets au fichier avant de l'exporter, cela fonctionne pour moi. Avant de faire ce système seulement le travail sous Windows et HP-UX, mais pas sous Linux.

FileOutputStream fStream = new FileOutputStream( f );
final byte[] bom = new byte[] { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF };
OutputStreamWriter writer = new OutputStreamWriter( fStream, "UTF8" );
fStream.write( bom );

Avoir une nomenclature (3 octets, hex EF BB BF) UTF-8 au début du fichier. Dans le cas contraire Excel interprétera les données selon l'encodage par défaut de vos paramètres régionaux (par exemple CP1252) au lieu de utf-8

Génération fichier CSV pour Excel, comment avoir une nouvelle ligne à l'intérieur d'une valeur

Je suis sur Mac, dans mon cas, je devais juste spécifier le séparateur avec "sep=;\n" et encoder le fichier en UTF-16LE comme ceci:

$data = "sep=;\n" .mb_convert_encoding($data, 'UTF-16LE', 'UTF-8');

Pour moi, aucun de la solution ci-dessus a travaillé. Voici ce que je l'ai fait pour résoudre le problème: modifier la valeur à l'aide de cette fonction dans le code de PHP:

$value = utf8_encode($value);

Cette sortie des valeurs correctement dans une feuille Excel.

J'eu ce même problème quand j'ai eu une routine Excel VBA que les données importées. Depuis CSV est un format de texte brut, je travaillais autour en ouvrant programatically les données dans un éditeur de fichiers simple comme WordPad, et ré-enregistrer sous forme de texte unicode, ou la copier dans le presse-papiers à partir de là et de le coller dans Excel. Si Excel ne parse automatiquement le CSV dans les cellules, ce qui est facile de remédier à l'aide de la construction « Texte à colonnes » caractéristique.

Le problème se produit toujours lorsque vous l'enregistrer dans un fichier txt et les ouvrir que dans Excel avec une virgule comme séparateur?

Le problème pourrait ne pas être l'encodage du tout, il est peut-être juste que le fichier n'est pas un fichier CSV parfait selon les normes Excel.

Ce poste est assez vieux, mais après les heures d'essayer, je veux partager ma solution ... peut-être il aide quelqu'un Dealing avec Excel et Mac et CSV et trébuche sur cette menace. Je suis la génération d'un csv dynamique en sortie à partir d'une base de données avec les utilisateurs Excel à l'esprit. (UTF-8 avec BOM)

J'ai essayé beaucoup de iconv's mais ne pouvais pas obtenir allemand trémas travaillant dans Mac Excel 2004. Une solution: PHPExcel. Il est grand, mais pour mon projet un peu trop. Ce qui fonctionne pour moi est en train de créer le fichier csv et convertir ce fichier csv à xls avec ce PHPsnippet: csv2xls . le résultat xls fonctionne avec Excel allemand trémas (ä, ö, Ü, ...).

Je viens d'essayer ces en-têtes et a Excel 2013 sur un ordinateur Windows 7 PC pour importer le fichier CSV avec des caractères spéciaux correctement. Le Byte Order Mark (BOM) a été la dernière clé qui a fait fonctionner.

    header('Content-Encoding: UTF-8');
    header('Content-type: text/csv; charset=UTF-8');
    header("Content-disposition: attachment; filename=filename.csv");
    header("Pragma: public");
    header("Expires: 0");
    echo "\xEF\xBB\xBF"; // UTF-8 BOM

Dans le cas contraire, vous pouvez:

header("Content-type: application/x-download");
header("Content-Transfer-Encoding: binary");
header("Content-disposition: attachment; filename=".$fileName."");
header("Cache-control: private");

echo utf8_decode($output);

Solution facile pour Mac Excel 2008: Je me suis battu avec ce soo plusieurs fois, mais voici était ma solution facile: Ouvrez le fichier .csv dans textwrangler qui devrait ouvrir vos caractères UTF-8 correctement. Maintenant, dans la barre d'état en bas modifier le format de fichier de « Unicode (UTF-8) » à « Ouest (ISO Latin 1) » et enregistrez le fichier. Maintenant, allez à votre Mac Excel 2008 et sélectionnez Fichier> Importer> Sélectionnez csv> Trouvez votre fichier> origine du fichier sélectionnez « Windows (ANSI) » et le tour est joué l'UTF-8 caractères affichent correctement. Au moins il fait pour moi ...

J'utilise cela et il fonctionne

header('Content-Description: File Transfer');
header('Content-Type: text/csv; charset=UTF-16LE');
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');
// output headers so that the file is downloaded rather than displayed
// create a file pointer connected to the output stream
$output = fopen('php://output', 'w');
fputs( $output, "\xEF\xBB\xBF" );
// output the column headings
fputcsv($output, array('Thông tin khách hàng đăng ký'));
// fetch the data
$setutf8 = "SET NAMES utf8";
$q = $conn->query($setutf8);
$setutf8c = "SET character_set_results = 'utf8', character_set_client =
'utf8', character_set_connection = 'utf8', character_set_database = 'utf8',
character_set_server = 'utf8'";
$qc = $conn->query($setutf8c);
$setutf9 = "SET CHARACTER SET utf8";
$q1 = $conn->query($setutf9);
$setutf7 = "SET COLLATION_CONNECTION = 'utf8_general_ci'";
$q2 = $conn->query($setutf7);
$sql = "SELECT id, name, email FROM myguests";
$rows = $conn->query($sql);
$arr1= array();
if ($rows->num_rows > 0) {
// output data of each row
while($row = $rows->fetch_assoc()) {
    $rcontent = " Name: " . $row["name"]. " - Email: " . $row["email"];  
    $arr1[]["title"] =  $rcontent;
}
} else {
     echo "0 results";
}
$conn->close();
// loop over the rows, outputting them
foreach($arr1 as $result1):
   fputcsv($output, $result1);
endforeach;

#output UTF-8 CSV en PHP que Excel lire correctement.

//Use tab as field separator   
$sep  = "\t";  
$eol  = "\n";    
$fputcsv  =  count($headings) ? '"'. implode('"'.$sep.'"', $headings).'"'.$eol : '';
//convert UTF-8 file without BOM to UTF-16LE for excel on mac
$fileUtf8String = file_get_contents("file.ext");
file_put_contents("file.ext", "\xFF\xFE" . mb_convert_encoding($fileUtf8String, "UTF-16LE", "UTF-8"));
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top