Question

Je suis en train de créer un fichier CSV en utilisant php. Comment puis-je imprimer des caractères non ascii?

Était-ce utile?

La solution

Il est possible d'utiliser des caractères unicode dans des fichiers CSV, assurez-vous d'utiliser les bons en-têtes HTTP. Cela fonctionne très bien dans OpenOffice, mais si je me souviens bien Excel a quelques problèmes pour afficher les fichiers CSV avec des caractères unicode.

En outre, vous devriez essayer d'utiliser fputcsv , il facilite les choses. Lorsque vous créez des fichiers à la volée, vous pouvez utiliser le flux de sortie php .

Alors quelque chose comme ceci:

$handle = fopen("php://output", "w");

header("Content-Type: text/csv; charset=UTF-8");
fputcsv($handle, $fields, ';', '"');

fclose($handle);

EDIT Après avoir lu vos commentaires, il semble que vous avez des problèmes de conversion htmlentities comme é. Pour convertir ces entités que vous devez vous assurer que chaque champ est décodé. Vous pouvez le faire avec html_entity_decode comme ceci:

$decoded_string = html_entity_decode($string, ENT_QUOTES, 'UTF-8');

BTW, la plupart du temps ce n'est pas une bonne idée de stocker du texte avec htmlentities dans une base de données, parce que quand vous ne voulez pas html de sortie (comme dans ce cas), vous devez les convertir en caractères réels. Il est plus facile de stocker tout le texte unicode.

Autres conseils

fputcsv doit gérer utf-8.

Voici ce que je l'utilise, je suis sûr qu'il pourrait utiliser un peu de raffinage pour votre situation mais dans l'ensemble très générique et très utile pour de nombreuses situations.

Vous nourrir juste la fonction SQL et il va cracher un csv avec une ligne d'en-tête des noms de colonnes.

<?php
function exportMysqlToCsv($csvsql,$filename = 'export.csv')
{
    $csv_terminated = "\n";
    $csv_separator = ",";
    $csv_enclosed = '"';
    $csv_escaped = "\\";
    $sql_query = $csvsql;

    // Gets the data from the database
    $result = mysql_query($sql_query);
    $fields_cnt = mysql_num_fields($result);


    $schema_insert = '';

    for ($i = 0; $i < $fields_cnt; $i++)
    {
        $l = $csv_enclosed . str_replace($csv_enclosed, $csv_escaped . $csv_enclosed,
            stripslashes(mysql_field_name($result, $i))) . $csv_enclosed;
        $schema_insert .= $l;
        $schema_insert .= $csv_separator;
    } // end for

    $out = trim(substr($schema_insert, 0, -1));
    $out .= $csv_terminated;

    // Format the data
    while ($row = mysql_fetch_array($result))
    {
        $schema_insert = '';
        for ($j = 0; $j < $fields_cnt; $j++)
        {
            if ($row[$j] == '0' || $row[$j] != '')
            {

                if ($csv_enclosed == '')
                {
                    $schema_insert .= $row[$j];
                } else
                {
                    $meta = mysql_fetch_field($result, $j);
                    if($meta->type == "int" || $meta->type == "real")
                    {
                      $schema_insert .= $row[$j];
                    } else {
                      $schema_insert .= $csv_enclosed . str_replace($csv_enclosed, $csv_escaped . $csv_enclosed, $row[$j]) . $csv_enclosed;
                    }
                }
            } else
            {
                $schema_insert .= '';
            }

            if ($j < $fields_cnt - 1)
            {
                $schema_insert .= $csv_separator;
            }
        } // end for

        $out .= $schema_insert;
        $out .= $csv_terminated;
    } // end while

    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Content-Length: " . strlen($out));
    // Output to browser with appropriate mime type, you choose ;)
    header("Content-type: text/x-csv");
    //header("Content-type: text/csv");
    //header("Content-type: application/csv");
    header("Content-Disposition: attachment; filename=$filename");
    echo $out;
    exit;

} 
?>

Comme vous le dites, ils sont générés à la volée (à savoir que vous utilisez echo etc pour les sorties directement), puis en suivant aiderai:

1) Ajouter cet en-tête au début de votre code PHP:

 header ('Content-type: text/csv; charset=utf-8');

2) Ajouter cette méta dans le code HTML:

 <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">

3) Enregistrez votre fichier de code PHP comme UTF-8 sans BOM .

Lorsque vous sélectionnez l'info page pour la page Web, vérifiez quel est l'encodage du fichier. Son devrait être UTF-8. Dans le cas contraire, les données que vous produisez est non UTF.
Veuillez également ce que l'encodage de votre navigateur caractère a défini. Dans Firefox son dans Menu-> view-> encodage de caractères.

en fait la réponse de shamittomar est très agréable mais il manque une chose

votre problème est lié à l'encodage
vous devez convertir votre encodage de texte en UTF-8 depuis PHP en utilisant en interne ascii

exemple:

$str = mb_convert_encoding($str , "UTF-8") ; 

consulter le php.net pour plus d'informations

Le meilleur exemple que j'ai trouvé est celui-ci.         

    function str_to_csv($row) {
        if ($row == '') {
            return array();
        }
        $a = array();
        $src = explode(',', $row);
        do {
            $p = array_shift($src);
            while (mb_substr_count($p, '"') % 2 != 0) {
                if (count($src) == 0) {
                    return false;
                }
                $p .= ',' . array_shift($src);
            }
            $match = null;
            if (preg_match('/^"(.+)"[\r\n]*$/', $p, $match)) {
                $p = $match[1];
            }
            $a[] = str_replace('""', '"', $p);
        } while (count($src) > 0);
        return $a;
    }

    function file_getcsv($f) {
        $line = fgets($f);
        while (($a = str_to_csv($line)) === false) {
            if (feof($f)) {
                return false;
            }
            $line .= "\n" . fgets($f);
        }
        return $a;
    }

    function file_to_csv($filename) {
        ini_set("auto_detect_line_endings", true);
        $a = array();
        $f = fopen($filename, 'r');
        while (!feof($f)) {
            $rec = file_getcsv($f);
            if ($rec === false) {
                return false;
            }
            if (!empty($rec)) {
                $a[] = $rec;
            }
        }
        fclose($f);
        return $a;
    }

    $data = file_to_csv('base2.csv');

    echo '<pre>';
    print_r($data);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top