Как я могу вывести CSV UTF-8 в PHP, который Excel будет правильно читать?
-
30-09-2019 - |
Вопрос
У меня есть это очень простое, что просто выводит некоторые вещи в формате 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 просто добавляет эти три персонажа к самой первой ячейке, когда он импортирует, и все же посылает специальные символы.
Решение
Цитировать Инженер поддержки Microsoft,
Excel для Mac в настоящее время не поддерживает UTF-8
Обновление, 2017.: Это верно для всех версий Microsoft Excel для Mac перед Офис 2016.. Отказ Новые версии (от Office 365) теперь поддерживают UTF-8.
Чтобы вывести контент UTF-8, который Excel как на Windows, так и в OS X смогут успешно читать, вам нужно будет делать две вещи:
Убедитесь, что вы преобразуете свой текст UTF-8 в UTF-16LE
mb_convert_encoding($csv, 'UTF-16LE', 'UTF-8');
Убедитесь, что вы добавляете марку заказа байта UTF-16LE
chr(255) . chr(254)
Следующая проблема, которая появляется только с Excel на OS X (но но нет Windows) будет при просмотре файла CSV с разделенными запятыми значениями, Excel будет представлять строки только одним ряд и всеми текстом вместе с запятыми в первом ряду.
Способ избежать этого - использовать вкладки в качестве разделенного значения.
я использовал Эта функция из комментариев PHP (Используя вкладки « T» вместо запятых), и он отлично работал на OS X и Windows Excel.
Обратите внимание, что для исправления проблемы с пустым столбцом в качестве конца строки, чтобы я должен был изменить линию код, который говорит:
$field_cnt = count($fields);
к
$field_cnt = count($fields)-1;
Поскольку некоторые другие комментарии на этой странице говорят, другие приложения для электронных таблиц, таких как OpenOffice Calc, собственные номера Apple и электронная таблица Google Doc не имеют проблем с файлами UTF-8 с запятыми.
Видеть Таблица в этом вопросе Для того, что работает и не работает для файлов CSV Unicode в Excel
Как сбоку, я могу добавить, что если вы используете Композитор, вы должны посмотреть на добавление League\Csv
Вашему требует. League\Csv
имеет действительно хорошая API для построения файлов CSV.
Использовать League\Csv
С помощью этого метода создания файлов CSV проверить Этот пример
Другие советы
У меня такая же (или похожая) проблема.
В моем случае, если я добавлю BOM на вывод, он работает:
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
Я верю, что это довольно уродливый хак, но он работал для меня, по крайней мере, для окон Excel 2007. Не уверен, что это будет работать на Mac.
Вот как я сделал это (это подсказать браузер для загрузки файла 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();
Единственное, что он фиксировал проблему кодирования UTF8 в превью CSV, когда вы попадаете в космический бар на Mac .. Но не в Excel Mac 2008 ... не знаю, почему
Я просто имел дело с той же проблемой и придумал два решения.
Использовать Phpexcel. сорт Как предложено BPETERSON76.
- Использование этого класса генерирует наиболее широко совместимый файл, я смог генерировать файл из закодированных данных UTF-8, которые открыли штраф в Excel 2008 Mac, Excel 2007 Windows и Google Docs.
- Самая большая проблема с использованием phpexcel заключается в том, что она медленная и использует много памяти, которая не является проблемой для разумно размером файлов, но Если ваш файл Excel / CSV имеет сотни или тысячи строк, эта библиотека становится непригодной.
Вот метод PHP, который займет некоторые данные TSV и вывод файла Excel в браузер, обратите внимание, что использует писатель Excel5, что означает, что файл должен быть совместимым с более старыми версиями Excel, но у меня больше нет доступа к любому доступу Так что я не могу их проверить.
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; }
Из-за проблем с эффективностью с phpexcel я также должен был выяснить, как создать совместимый CSV CSV UTF-8 и Excel или TSV.
- Лучше всего я мог придумать, был файл, который был совместимым с Excel 2008 Mac и Excel 2007, но не Google Docs, который достаточно хорош для моего приложения.
- Я нашел решение здесь, конкретно, Этот ответ, но вы также должны прочитать принятый ответ Как это объясняет проблему.
Вот код PHP, который я использовал, обратите внимание, что я использую данные TSV (вкладки как разделители вместо запятых):
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;
У меня была такая же проблема, и она была решена, как показано ниже:
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 не поддерживает UTF-8. Вы должны кодировать ваш текст UTF-8 в UCS-2LE.
mb_convert_encoding($output, 'UCS-2LE', 'UTF-8');
Следить на этом:
Похоже, что проблема просто с Excel на Mac. Это не то, как я создаю файлы, потому что даже генерируя CSV от Excel ломает их. Я экономлю как CSV, а Reimport, и все символы запутались.
Итак ... не может быть правильным ответом на это. Спасибо за все предложения.
Я бы сказал, что от всего, что я прочитал, предложение @daniel Magliola о спецификации, вероятно, будет лучшим ответом на другой компьютер. Но это все еще не решает мою проблему.
В моем случае следующее работает очень приятно сделать CSV-файл с помощью utf-8 Chars, отображаемых правильно в Excel.
$out = fopen('php://output', 'w');
fprintf($out, chr(0xEF).chr(0xBB).chr(0xBF));
fputcsv($out, $some_csv_strings);
То 0xEF 0xBB 0xBF
Бом-заголовок позволит Excel знать правильное кодирование.
Это отлично работает в Excel для Windows, а также Mac OS.
Исправлены проблемы в Excel, которые не отображают символы, содержащие диакритические, кириллицы, греческие буквы и символы валюты.
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;
}
CSV-файл MUSST включает знак заказа байта.
Или как предложено и обходной путь просто повторить его с HTTP Cody
Поскольку кодировка UTF8 не хорошо воспроизводится с Excel. Вы можете преобразовать данные в другой тип кодирования, используя iconv()
.
например
iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $value),
Добавлять:
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);
Конвертирование уже UTF-8 закодированный текст с помощью mb_convert_encoding
не нужен. Просто добавьте три символа перед исходным контентом:
$newContent = chr(239) . chr(187) . chr(191) . $originalContent
Для меня это решило проблему специальных символов в файлах CSV.
Как я исследовал, и я обнаружил, что 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
**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;
}
Как насчет просто вывода самого Excel? Это отличный класс Это позволяет вам генерировать XL-файлы сервера. Я часто использую его для клиентов, которые не могут «выяснить» CSV, и до сих пор никогда не было жалобы. Это также позволяет некоторое дополнительное форматирование (затенение, rowheights, расчеты и т. Д.), что CSV никогда не будет делать.
Вы можете преобразовать свою строку 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) );
Вы должны использовать кодировку «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);
}
Вы можете добавить 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 BOM (3 байта, Hex EF BB BF) в начале файла. В противном случае Excel будет интерпретировать данные в соответствии с кодировкой вашей локали (например, CP1252) вместо UTF-8
Создание файла CSV для Excel, как иметь новую строку внутри значения
Я на Mac, в моем случае мне просто пришлось указать сепаратор с "sep=;\n"
и кодируйте файл в UTF-16LE, как это:
$data = "sep=;\n" .mb_convert_encoding($data, 'UTF-16LE', 'UTF-8');
Для меня ни одно из решений выше не работало. Ниже приведен то, что я сделал, чтобы решить проблему: измените значение, используя эту функцию в коде PHP:
$value = utf8_encode($value);
Это выходные значения правильно в листе Excel.
У меня была эта же проблема, когда у меня была рутина Excel VBA, которые импортируют данные. Поскольку CSV - это простой текстовый формат, я работал вокруг этого, разработал данные в простом файловом редакторе, как WordPad, и восстановить его в виде текста Unicode, или копировать его в буфер обмена оттуда и вставляя его в Excel. Если Excel не анализирует автоматически CSV в ячейки, это легко исправлена, используя встроенный «текст в столбцы».
Проблема все еще возникает, когда вы сохраняете его как файл .txt, и они открывают, что в Excel с запятой в качестве разделителя?
Проблема может не быть кодировкой вообще, это может быть просто файл не является идеальным CSV в соответствии со стандартами Excel.
Этот пост довольно старый, но после часов попыток я хочу поделиться своим решением ... Может быть, это помогает кому-либо иметь дело с Excel и Mac и CSV и спотыкаться над этой угрозой. Я генерирую CSV динамически как вывод из базы данных с учетом пользователей Excel. (UTF-8 с BOM)
Я попробовал много iconv, но не мог получить немецкие умлауты, работающие в Mac Excel 2004. Одно решение: phpexcel. Это здорово, но для моего проекта слишком много. Что работает для меня, создает файл CSV и преобразовать этот файл CSV в XLS с помощью этого phpsnippet: CSV2XLS.. Отказ Результат XLS работает с Excel German Umlauts (Ä, Ö, ü, ...).
Я просто попробовал эти заголовки и получил Excel 2013 на PC Windows 7, чтобы правильно импортировать файл CSV специальными символами. Марк заказа байта (BOM) был окончательным ключом, который сделал его работу.
заголовок (кодирование контента: UTF-8 '); Заголовок (тип контента: Text / CSV; Charset = UTF-8 '); Заголовок («Успокой из контента: вложение; filename = filename.csv»); Заголовок («Прагма: Общественный»); Заголовок («Истекает: 0»); echo " xef xbb xbf"; // utf-8 bom
В противном случае вы можете:
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);
Простое решение для Mac Excel 2008: я боролся с этим SOO много раз, но вот было мое простое исправление: откройте файл .csv в TextWrangler, который должен правильно открывать ваши символы UTF-8. Теперь в нижней панели состояния измените формат файла из «Unicode (UTF-8)» на «Western (ISO Latin 1)» и сохранить файл. Теперь перейдите к вашему Mac Excel 2008 и выберите «Файл»> «Импорт»> «Выбрать CSV»> «Найти свой файл»> «Вход» Выберите «Windows (ANSI)» и VOILA The Chars UTF-8 отображается правильно. По крайней мере, это делает для меня ...
Я использую это, и это работает
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;
#OUTOUT ATF-8 CSV в PHP, который Excel будет читать правильно.
//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"));