Как я могу вывести UTF-8 CSV на PHP, который Excel будет читать правильно? - PullRequest
174 голосов
/ 03 декабря 2010

У меня есть очень простая вещь, которая просто выводит некоторые вещи в формате CSV, но это должен быть UTF-8. Я открываю этот файл в TextEdit или TextMate или Dreamweaver, и он правильно отображает символы UTF-8, но если я открываю его в Excel, он делает это глупо - вместо этого. Вот что у меня во главе моего документа:

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

Кажется, что все это имеет желаемый эффект, за исключением того, что Excel (Mac, 2008) не хочет импортировать его должным образом. В Excel нет вариантов «открыть как UTF-8» или что-то в этом роде, так что ... я немного раздражаюсь.

Кажется, я нигде не могу найти чёткого решения, несмотря на то, что у многих людей такая же проблема. Больше всего я вижу включение спецификации, но я не могу точно понять, как это сделать. Как вы можете видеть выше, я просто echo пользуюсь этими данными, я не пишу никаких файлов. Я могу сделать это, если мне нужно, просто нет, потому что на данный момент в этом нет необходимости. Любая помощь?

Обновление: я попытался повторить спецификацию как echo pack("CCC", 0xef, 0xbb, 0xbf);, которую я только что извлек с сайта, который пытался обнаружить спецификацию. Но Excel просто добавляет эти три символа в самую первую ячейку при импорте и все еще портит специальные символы.

Ответы [ 30 ]

4 голосов
/ 19 ноября 2012

Поскольку кодировка UTF8 не очень хорошо работает с Excel. Вы можете преобразовать данные в другой тип кодировки, используя iconv().

, например

iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $value),
4 голосов
/ 15 марта 2016

Добавить:

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

Или:

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

Перед записью любого содержимого в файл CSV.

Пример:

<?php
$file = fopen( "file.csv", "w");
fprintf( $file, "\xEF\xBB\xBF");
fputcsv( $file, ["english", 122, "বাংলা"]);
fclose($file);
2 голосов
/ 16 сентября 2014

Преобразование уже закодированного в UTF-8 текста с использованием mb_convert_encoding не требуется.Просто добавьте три символа перед исходным содержимым:

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

Для меня это решило проблему специальных символов в CSV-файлах.

2 голосов
/ 27 марта 2018
**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;
}
2 голосов
/ 17 апреля 2017

Как я выяснил, я обнаружил, что UTF-8 не работает хорошо на MAC и Windows, поэтому я попробовал с Windows-1252, он хорошо поддерживает их обоих, но вы должны выбрать тип кодировки в Ubuntu.Вот мой код $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
1 голос
/ 04 декабря 2010

Как насчет того, чтобы просто выводить данные в сам Excel? Это отличный класс , который позволяет создавать файлы XLS на стороне сервера.Я часто использую его для клиентов, которые не могут «выяснить» CSV и до сих пор никогда не жаловались.Он также допускает дополнительное форматирование (затенение, высоту строк, вычисления и т. Д.), Которое csv никогда не сделает.

1 голос
/ 14 мая 2012

вы можете конвертировать вашу строку CSV с iconv . например:

$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) );
1 голос
/ 10 апреля 2013

Вы должны использовать кодировку «Windows-1252».

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

Возможно, вам придется преобразовать строки:

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

  return iconv($encoding, "Windows-1252", $string);
}
1 голос
/ 23 октября 2013

Вы можете добавить 3 байта в файл перед экспортом, у меня это работает. До этого система работала только в Windows и HP -UX, но не работала в 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 );

В начале файла есть спецификация UTF-8 (3 байта, шестнадцатеричная EF BB BF). В противном случае Excel будет интерпретировать данные в соответствии с кодировкой по умолчанию для вашей локали (например, cp1252) вместо utf-8

Создание CSV-файла для Excel, как добавить новую строку в значение

1 голос
/ 07 декабря 2016

Для меня ни одно из вышеприведенных решений не сработало.Ниже описано, что я сделал для решения проблемы: измените значение с помощью этой функции в коде PHP:

$value = utf8_encode($value);

Это выводит значения правильно в листе Excel.

...