Question

J'exporte par programme des données (à l'aide de PHP 5.2) dans un fichier test .csv.
Exemple de données: Numéro 1 (notez le e accentué). Les données sont utf-8 (pas de nomenclature ajoutée).

Lorsque j'ouvre ce fichier dans MS Excel, il affiche Numéro 1.

Je peux l’ouvrir dans un éditeur de texte (UltraEdit) qui l’affiche correctement. L'UE indique que le caractère est decimal 233.

Comment puis-je exporter du texte dans un fichier .csv afin que MS Excel le rende correctement , de préférence sans forcer l'utilisation de l'assistant d'importation paramètres par défaut de l'assistant?

Était-ce utile?

La solution

Un fichier UTF8 correctement formaté peut avoir un marque d'ordre d'octet comme ses trois premiers octets. Ce sont les valeurs hexadécimales 0xEF, 0xBB, 0xBF. Ces octets servent à marquer le fichier comme UTF8 (car ils ne sont pas pertinents en tant que & Quot; ordre d'octet & "; Informations). 1 Si cette nomenclature n'existe pas, le consommateur / lecteur est autorisé à en déduire le type de codage du texte. Les lecteurs qui ne sont pas compatibles UTF8 liront les octets comme un autre encodage tel que Windows-1252 et afficheront les caractères  au début du fichier.

Il existe un bug connu dans lequel Excel, lors de l'ouverture de fichiers CSV UTF8 via une association de fichiers, suppose qu'ils sont dans un codage sur un octet, ne tenant pas compte de la présence de la nomenclature UTF8. Cela ne peut pas être résolu par la page de code ou le paramètre de langue par défaut du système. La nomenclature ne sera pas renseignée dans Excel - cela ne fonctionnera tout simplement pas. (Un rapport minoritaire affirme que la nomenclature déclenche parfois l'assistant & "Importation de texte &";). Ce bogue semble exister dans Excel 2003 et les versions antérieures. La plupart des rapports (parmi les réponses fournies ici) indiquent que cela est corrigé dans Excel 2007 et les versions plus récentes.

Notez que vous pouvez toujours * ouvrir correctement les fichiers UTF8 CSV dans Excel à l'aide de la commande & "Importer du texte &"; assistant, qui vous permet de spécifier le codage du fichier que vous ouvrez. Bien sûr, cela est beaucoup moins pratique.

Les lecteurs de cette réponse sont très probablement dans une situation où ils ne prennent pas particulièrement en charge Excel < 2007, mais nous envoyons du texte UTF8 brut à Excel, ce qui l’interprète de manière erronée et saupoudre votre texte de à caractères similaires avec d’autres caractères Windows-1252. L'ajout de la nomenclature UTF8 est probablement la solution la plus rapide et la plus adaptée.

Si vous êtes coincé avec des utilisateurs d'Excel plus anciens et qu'Excel est le seul consommateur de vos CSV, vous pouvez contourner ce problème en exportant UTF16 au lieu de UTF8. Excel 2000 et 2003 double-cliquer-ouvrir ces correctement. (Certains autres éditeurs de texte peuvent avoir des problèmes avec UTF16. Vous devrez donc peut-être peser vos options avec soin.)

* Sauf si vous ne pouvez pas (au moins), l'assistant d'importation d'Excel 2011 pour Mac ne fonctionne pas toujours avec tous les encodages, quel que soit ce que vous lui indiquez. < / anecdotal-evidence > :)

Autres conseils

La préparation d’une nomenclature (\ uFEFF) au préalable a fonctionné pour moi (Excel 2007), dans laquelle Excel reconnaissait le fichier UTF-8. Sinon, le sauvegarder et utiliser l'assistant d'importation fonctionnent, mais sont moins idéaux.

Vous trouverez ci-dessous le code PHP que j'utilise dans mon projet lors de l'envoi de Microsoft Excel à l'utilisateur:

  /**
   * Export an array as downladable Excel CSV
   * @param array   $header
   * @param array   $data
   * @param string  $filename
   */
  function toCSV($header, $data, $filename) {
    $sep  = "\t";
    $eol  = "\n";
    $csv  =  count($header) ? '"'. implode('"'.$sep.'"', $header).'"'.$eol : '';
    foreach($data as $line) {
      $csv .= '"'. implode('"'.$sep.'"', $line).'"'.$eol;
    }
    $encoded_csv = mb_convert_encoding($csv, 'UTF-16LE', 'UTF-8');
    header('Content-Description: File Transfer');
    header('Content-Type: application/vnd.ms-excel');
    header('Content-Disposition: attachment; filename="'.$filename.'.csv"');
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: '. strlen($encoded_csv));
    echo chr(255) . chr(254) . $encoded_csv;
    exit;
  }

UPDATED: L’amélioration du nom de fichier et le calcul de la longueur correcte ont été corrigés par le bogue. Merci à TRiG et à @ ivanhoe011

La réponse à toutes les combinaisons de versions d'Excel (2003 + 2007) et de types de fichiers

La plupart des autres réponses ici concernent uniquement leur version Excel et ne vous aideront pas nécessairement, car leur réponse pourrait ne pas être vraie pour votre version d'Excel.

Par exemple, l'ajout du caractère de nomenclature crée des problèmes de reconnaissance automatique du séparateur de colonnes, mais pas avec toutes les versions d'Excel.

Trois variables déterminent si cela fonctionne dans la plupart des versions d'Excel:

  • Encodage
  • Présence de caractère de nomenclature
  • Séparateur de cellules

Quelqu'un de stoïque chez SAP a essayé chaque combinaison et a rendu compte du résultat. Résultat final? Utilisez UTF16le avec la nomenclature et le caractère de tabulation comme séparateur pour qu'il fonctionne dans la plupart des versions d'Excel.

Tu ne me crois pas? Je ne le ferais pas non plus, mais lisez ici et pleurez: http://wiki.sdn.sap.com/wiki/display/ABAP/CSV+tests+of+encoding+and+column+separator

sélectionnez le format UTF-8 lors de l’importation. Si vous utilisez Office 2007, c'est à cet endroit que vous l'avez choisi: juste après l'ouverture du fichier.

Écho de la nomenclature UTF-8 avant la sortie des données CSV. Cela corrige tous les problèmes de personnage dans Windows mais ne fonctionne pas pour Mac.

echo "\xEF\xBB\xBF";

Cela fonctionne pour moi car je dois générer un fichier qui sera utilisé uniquement sur les ordinateurs Windows.

UTF-8 ne fonctionne pas pour moi dans Office 2007 sans service pack, avec ou sans nomenclature. (U + ffef ou 0xEF, 0xBB, 0xBF, ni ne fonctionne) L’installation de sp3 permet à UTF-8 de fonctionner lorsque la nomenclature 0xEF, 0xBB, 0xBF est ajoutée au début.

UTF-16 fonctionne lors de l'encodage en python avec & "utf-16-le &"; avec un 0xff 0xef Nomenclature préfixée et utilisation de la tabulation comme séparateur. J'ai dû écrire manuellement la nomenclature, puis utiliser & "Utf-16-le &"; plutôt que & "; utf-16 &"; sinon chaque encode () a ajouté la nomenclature à chaque ligne écrite qui est apparu comme un déchet sur la première colonne de la deuxième ligne et après.

ne peut pas dire si UTF-16 fonctionnerait sans aucun sp installé, car Je ne peux pas y retourner maintenant. soupir

C’est sous Windows, ne sais pas comment utiliser Office pour MAC.

pour les deux cas de travail, l’importation fonctionne lors du lancement d’un téléchargement directement depuis le navigateur et l'assistant d'importation de texte n'intervient pas, il fonctionne comme vous le souhaitiez.

Comme le dit Fregal, \ uFef est la voie à suivre.

<%@LANGUAGE="JAVASCRIPT" CODEPAGE="65001"%>
<%
Response.Clear();
Response.ContentType = "text/csv";
Response.Charset = "utf-8";
Response.AddHeader("Content-Disposition", "attachment; filename=excelTest.csv");
Response.Write("\uFEFF");
// csv text here
%>

J'ai également remarqué que la question était " répondu " Il y a quelques temps, mais je ne comprends pas les histoires qui disent que vous ne pouvez pas ouvrir un fichier CSV encodé en utf8 dans Excel sans utiliser l'assistant de texte.

Mon expérience reproductible: Tapez Old MacDonald had a farm,ÈÌÉÍØ dans le Bloc-notes, appuyez sur Entrée, puis sur Enregistrer sous (avec l'option UTF-8).

Utilisation de Python pour afficher les éléments réellement présents:

>>> open('oldmac.csv', 'rb').read()
'\xef\xbb\xbfOld MacDonald had a farm,\xc3\x88\xc3\x8c\xc3\x89\xc3\x8d\xc3\x98\r\n'
>>> ^Z

Bien. Le Bloc-notes a mis une nomenclature à l'avant.

Allez maintenant dans l'Explorateur Windows, double-cliquez sur le nom du fichier ou cliquez avec le bouton droit de la souris et utilisez & "Ouvrir avec ... &"; / p>

Vous pouvez enregistrer un fichier HTML avec l’extension 'xls' et les accents fonctionneront (avant 2007 au moins).

Exemple: enregistrez ceci (en utilisant Enregistrer sous utf8 dans le Bloc-notes) sous le nom test.xls:

<html>
<meta http-equiv="Content-Type" content="text/html" charset="utf-8" />
<table>
<tr>
  <th>id</th>
  <th>name</th>
</tr>
<tr>
 <td>4</td>
 <td>Hélène</td>
</tr>
</table>
</html>

C’est juste une question de codage de caractères. Il semble que vous exportiez vos données au format UTF-8: & # 233; Dans UTF-8, la séquence à deux octets 0xC3 0xA9 est interprétée dans Windows-1252 avec & # 195; & # 169 ;. Lorsque vous importez vos données dans Excel, assurez-vous de préciser que le codage de caractères que vous utilisez est UTF-8.

Le format CSV est implémenté au format ASCII et non au format Unicode dans Excel, ce qui permet de modifier les signes diacritiques. Nous avons rencontré le même problème, et c’est ainsi que j’ai découvert que la norme CSV officielle était définie comme étant basée sur ASCII dans Excel.

L'écriture d'une nomenclature dans le fichier CSV de sortie a bien fonctionné pour moi dans Django:

def handlePersoonListExport(request):
    # Retrieve a query_set
    ...

    template = loader.get_template("export.csv")
    context = Context({
        'data': query_set,
    })

    response = HttpResponse()
    response['Content-Disposition'] = 'attachment; filename=export.csv'
    response['Content-Type'] = 'text/csv; charset=utf-8'
    response.write("\xEF\xBB\xBF")
    response.write(template.render(context))

    return response

Pour plus d'informations, http: //crashcoursing.blogspot .com / 2011/05 / export-csv-with-special-characters.html Merci les gars!

Une autre solution que j'ai trouvée consistait simplement à coder le résultat sous forme de code Windows (Windows-1252 ou CP1252). Cela serait fait, par exemple, en définissant Content-Type de manière appropriée sur quelque chose comme text/csv; charset=Windows-1252 et en définissant de la même manière le codage de caractères du flux de réponses.

Notez que l'inclusion de la nomenclature UTF-8 n'est pas nécessairement une bonne idée. Les versions Mac d'Excel l'ignorent et affichent en fait la nomenclature au format ASCII & # 8230; trois méchants caractères au début du premier champ de votre feuille de calcul & # 8230;

Vérifiez le codage dans lequel vous générez le fichier. Pour que Excel affiche correctement le fichier, vous devez utiliser la page de codes par défaut du système.

Quelle langue utilisez-vous? si c'est .Net, vous devez uniquement utiliser Encoding.Default lors de la génération du fichier.

Excel 2007 lit correctement les fichiers au format Csv codés en BOM (EF BB BF) au format UTF-8.

Excel 2003 (et peut-être plus tôt) lit UTF-16LE avec BOM (FF FE), mais avec des tabulations au lieu de virgules ou de points-virgules.

Je ne peux obtenir que le format CSV correctement analysé dans Excel 2007 en tant que UTF-16 little-endian séparé par des tabulations, en commençant par le repère d'ordre des octets approprié.

Si vous avez le même code vb.net que le mien, le code suivant a fonctionné pour moi:

    Response.Clear()
    Response.ClearHeaders()
    Response.ContentType = "text/csv"
    Response.Expires = 0
    Response.AddHeader("Content-Disposition", "attachment; filename=export.csv;")
    Using sw As StreamWriter = New StreamWriter(Context.Response.OutputStream, System.Text.Encoding.Unicode)
        sw.Write(csv)
        sw.Close()
    End Using
    Response.End()

J'ai trouvé un moyen de résoudre le problème. C'est un bidouillage méchant mais qui fonctionne: ouvrez la doc avec Open Office , puis enregistrez-la au format Excel; le .xls ou .xlsx résultant affichera les caractères accentués.

Avec Ruby 1.8.7, je code chaque champ en UTF-16 et jette la nomenclature (peut-être).

Le code suivant est extrait de active_scaffold_export:

<%                                                                                                                                                                                                                                                                                                                           
      require 'fastercsv'                                                                                                                                                                                                                                                                                                        
      fcsv_options = {                                                                                                                                                                                                                                                                                                           
        :row_sep => "\n",                                                                                                                                                                                                                                                                                                        
        :col_sep => params[:delimiter],                                                                                                                                                                                                                                                                                          
        :force_quotes => @export_config.force_quotes,                                                                                                                                                                                                                                                                            
        :headers => @export_columns.collect { |column| format_export_column_header_name(column) }                                                                                                                                                                                                                                
      }                                                                                                                                                                                                                                                                                                                          

      data = FasterCSV.generate(fcsv_options) do |csv|                                                                                                                                                                                                                                                                           
        csv << fcsv_options[:headers] unless params[:skip_header] == 'true'                                                                                                                                                                                                                                                      
        @records.each do |record|                                                                                                                                                                                                                                                                                                
          csv << @export_columns.collect { |column|                                                                                                                                                                                                                                                                              
            # Convert to UTF-16 discarding the BOM, required for Excel (> 2003 ?)                                                                                                                                                                                                                                     
            Iconv.conv('UTF-16', 'UTF-8', get_export_column_value(record, column))[2..-1]                                                                                                                                                                                                                                        
          }                                                                                                                                                                                                                                                                                                                      
        end                                                                                                                                                                                                                                                                                                                      
      end                                                                                                                                                                                                                                                                                                                        
    -%><%= data -%>

La ligne importante est la suivante:

Iconv.conv('UTF-16', 'UTF-8', get_export_column_value(record, column))[2..-1]

ouvrez le fichier csv avec notepad ++ cliquez sur Encoder, sélectionnez convertir en UTF-8 (pas convertir en UTF-8 (sans nomenclature)) sauvegarder ouvert par double clic avec excel J'espère que l'aide Christophe GRISON

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top