Можно ли заставить Excel автоматически распознавать файлы CSV UTF-8?
Я разрабатываю часть приложения, которое отвечает за экспорт некоторых данных в файлы CSV. Приложение всегда использует UTF-8 из-за его многоязычности на всех уровнях. Но открытие таких файлов CSV (содержащих, например, диакритические знаки, буквы кириллицы, греческие буквы) в Excel не дает ожидаемых результатов, показывающих что-то вроде Г„/Г¤, Г–/Г¶
, И я не знаю, как заставить Excel понять, что открытый CSV-файл закодирован в UTF-8. Я также попытался указать спецификацию UTF-8 EF BB BF
, но Excel игнорирует это.
Есть ли обходной путь?
PS Какие инструменты могут вести себя как Excel?
ОБНОВИТЬ
Я должен сказать, что я перепутал сообщество с формулировкой вопроса. Когда я задавал этот вопрос, я попросил способ открыть файл CSV UTF-8 в Excel без каких-либо проблем для пользователя, бегло и прозрачно. Однако я использовал неправильную формулировку, прося сделать это автоматически. Это очень запутанно, и это противоречит автоматизации макросов VBA. Есть два ответа на этот вопрос, которые я ценю больше всего: самый первый ответ Алекса https://stackru.com/a/6002338/166589, и я принял этот ответ; и второй от Марка /questions/45246963/mozhno-li-zastavit-excel-avtomaticheski-raspoznavat-fajlyi-csv-utf-8/45247033#45247033 который появился чуть позже. С точки зрения удобства использования, у Excel, похоже, не было хорошей и удобной поддержки CSV в UTF-8, поэтому я считаю, что оба ответа верны, и сначала я принял ответ Алекса, потому что он действительно утверждал, что Excel не может сделать это прозрачно. Это то, что я тут перепутал автоматически. Ответ Марка помогает более продвинутым пользователям достичь ожидаемого результата. Оба ответа великолепны, но ответ Алекса немного лучше подходит для моего неясного вопроса.
ОБНОВЛЕНИЕ 2
Спустя пять месяцев после последнего редактирования я заметил, что ответ Алекса почему-то исчез. Я действительно надеюсь, что это не техническая проблема, и я надеюсь, что больше нет обсуждения того, какой ответ больше. Поэтому я принимаю ответ Марка как лучший.
34 ответа
Алекс прав, но так как вы должны экспортировать в CSV, вы можете дать пользователям этот совет при открытии файлов CSV:
- Сохраните экспортированный файл как CSV
- Открыть Excel
- Импортируйте данные, используя Данные -> Импорт внешних данных -> Импорт данных
- Выберите тип файла "CSV" и перейдите к вашему файлу
- В мастере импорта измените File_Origin на "65001 UTF" (или выберите правильный языковой символьный идентификатор)
- Поменяйте разделитель на запятую
- Выберите, куда импортировать и Готово
Таким образом, специальные символы должны отображаться правильно.
Маркер порядка следования байтов UTF-8 поможет Excel 2007+ понять, что вы используете UTF-8. (См. Этот пост).
В случае, если у кого-то возникли те же проблемы, что и у меня, класс кодирования.NET UTF8 не выводит маркер порядка байтов, даже если его конструктору явно сказано. Вы должны использовать этот обходной путь, если вы действительно хотите сохранить его с маркером порядка байтов.
Ошибка с игнорируемой спецификацией, похоже, исправлена в Excel 2013. У меня была та же проблема с кириллицей, но с добавлением символа спецификации \uFEFF
помогло
Невероятно, что есть так много ответов, но никто не отвечает на вопрос:
"Когда я задавал этот вопрос, я спросил, как открыть файл Excel в формате UTF-8 в Excel без каких-либо проблем для пользователя..."
Ответ, помеченный как принятый ответ с более чем 200 голосами "за", бесполезен для меня, потому что я не хочу давать своим пользователям инструкции по настройке Excel. Кроме того: это руководство будет применяться к одной версии Excel, но другие версии Excel имеют разные меню и диалоговые окна конфигурации. Вам понадобится руководство для каждой версии Excel.
Итак, вопрос в том, как сделать так, чтобы Excel показывал данные UTF8 простым двойным щелчком мыши?
По крайней мере, в Excel 2007 это невозможно, если вы используете файлы CSV, потому что спецификация UTF8 игнорируется, и вы увидите только мусор. Это уже часть вопроса Любомира Шайдарова:
"Я также пытался указать UTF-8 BOM EF BB BF, но Excel игнорирует это".
Я делаю то же самое: запись русских или греческих данных в CSV-файл UTF8 с спецификацией приводит к мусору в Excel:
Содержимое файла UTF8 CSV:
Colum1;Column2
Val1;Val2
Авиабилет;Tλληνικ
Результат в Excel 2007:
Решение состоит в том, чтобы вообще не использовать CSV. Этот формат реализован Microsoft настолько глупо, что зависит от настроек региона в панели управления, если в качестве разделителя используется запятая или точка с запятой. Таким образом, один и тот же файл CSV может правильно открываться на одном компьютере, но на другом компьютере нет. "CSV" означает "значения, разделенные запятыми", но, например, в немецкой Windows по умолчанию точка с запятой должна использоваться в качестве разделителя, в то время как запятая не работает. (Здесь он должен называться SSV = Значения, разделенные точкой с запятой). Файлы CSV нельзя обменивать между версиями Windows на разных языках. Это дополнительная проблема к проблеме UTF-8.
Excel существует с десятилетий. Жаль, что Microsoft не смогла реализовать такую основную вещь, как импорт CSV за все эти годы.
Однако, если вы поместите те же значения в файл HTML и сохраните этот файл как файл UTF8 с спецификацией с расширением XLS, вы получите правильный результат.
Содержимое файла ULS XTF8:
<table>
<tr><td>Colum1</td><td>Column2</td></tr>
<tr><td>Val1</td><td>Val2</td></tr>
<tr><td>Авиабилет</td><td>Tλληνικ</td></tr>
</table>
Результат в Excel 2007:
Вы даже можете использовать цвета в HTML, которые Excel будет отображать правильно.
<style>
.Head { background-color:gray; color:white; }
.Red { color:red; }
</style>
<table border=1>
<tr><td class=Head>Colum1</td><td class=Head>Column2</td></tr>
<tr><td>Val1</td><td>Val2</td></tr>
<tr><td class=Red>Авиабилет</td><td class=Red>Tλληνικ</td></tr>
</table>
Результат в Excel 2007:
В этом случае только сама таблица имеет черную рамку и линии. Если вы хотите, чтобы ВСЕ ячейки отображали линии сетки, это также возможно в HTML:
<html xmlns:x="urn:schemas-microsoft-com:office:excel">
<head>
<meta http-equiv="content-type" content="text/plain; charset=UTF-8"/>
<xml>
<x:ExcelWorkbook>
<x:ExcelWorksheets>
<x:ExcelWorksheet>
<x:Name>MySuperSheet</x:Name>
<x:WorksheetOptions>
<x:DisplayGridlines/>
</x:WorksheetOptions>
</x:ExcelWorksheet>
</x:ExcelWorksheets>
</x:ExcelWorkbook>
</xml>
</head>
<body>
<table>
<tr><td>Colum1</td><td>Column2</td></tr>
<tr><td>Val1</td><td>Val2</td></tr>
<tr><td>Авиабилет</td><td>Tλληνικ</td></tr>
</table>
</body>
</html>
Этот код даже позволяет указать имя листа (здесь "MySuperSheet")
Результат в Excel 2007:
Мы использовали этот обходной путь:
- Конвертировать CSV в UTF-16
- Вставить спецификацию в начале файла
- Использовать вкладку как разделитель полей
Были те же проблемы с PHP-генерируемыми CSV-файлами.
Excel игнорировал спецификацию, когда разделитель был определен через "sep=,\n"
в начале контента (но, конечно, после спецификации).
Так что добавив спецификацию ("\xEF\xBB\xBF"
) в начале содержимого и установка точки с запятой в качестве разделителя через fputcsv($fh, $data_array, ";");
делает трюк.
Это 2018 год, и я пришел из будущего, чтобы принести вам лучший и самый простой ответ.
Чтобы открыть файл с помощью двойного щелчка, на котором отображаются правильные символы:
- Щелкните правой кнопкой мыши и отредактируйте файл в Notepad ++,
- Найдите и выберите Encoding->UTF-8-BOM в верхнем меню, затем нажмите "Сохранить".
Пожалуйста. Я вернусь в 2025 году.
Старый вопрос, но, черт возьми, самое простое решение:
- Откройте CSV в блокноте
- Сохранить как -> выбрать правильную кодировку
- Откройте новый файл
У меня была такая же проблема в прошлом (как создавать файлы, которые Excel может читать, и другие инструменты также могут читать). Я использовал TSV, а не CSV, но возникла та же проблема с кодировками.
Мне не удалось найти способ заставить Excel автоматически распознавать UTF-8, и я не хотел / не мог навязать потребителям файлов сложные инструкции, как их открывать. Поэтому я закодировал их как UTF-16le (с спецификацией) вместо UTF-8. В два раза больше, но Excel может распознать кодировку. И они хорошо сжимаются, поэтому размер редко (но, к сожалению, никогда) имеет значение.
Как я написал на http://thinkinginsoftware.blogspot.com/2017/12/correctly-generate-csv-that-excel-can.html:
Скажите разработчику программного обеспечения, ответственному за создание CSV, чтобы исправить это. В качестве быстрого обходного пути вы можете использовать gsed для вставки спецификации UTF-8 в начало строки:
gsed -i '1s/^\(\xef\xbb\xbf\)\?/\xef\xbb\xbf/' file.csv
Эта команда вставляет спецификацию UTF-4, если она отсутствует. Поэтому это идемпотентная команда. Теперь вы сможете дважды щелкнуть файл и открыть его в Excel.
В php вы просто добавляете $bom к $csv_string:
$bom = sprintf( "%c%c%c", 239, 187, 191); // EF BB BF
file_put_contents( $file_name, $bom . $csv_string );
Протестировано в MS Excel 2016, php 7.2.4
Действительно поразительный список ответов, но, так как один довольно хороший ответ все еще отсутствует, я упомяну его здесь: откройте файл csv с листами Google и сохраните его на своем локальном компьютере в виде файла excel.
В отличие от Microsoft, Google удалось поддерживать CSV-файлы UTF-8, поэтому он просто открывает этот файл. И экспорт в формат Excel также просто работает. Таким образом, хотя это решение может и не быть предпочтительным для всех, оно довольно надежно, и количество кликов не так велико, как может показаться, особенно если вы уже вошли в Google.
Простой макрос VBA для открытия текстовых и CSV-файлов UTF-8
Sub OpenTextFile()
filetoopen = Application.GetOpenFilename("Text Files (*.txt;*.csv), *.txt;*.csv")
If filetoopen = Null Or filetoopen = Empty Then Exit Sub
Workbooks.OpenText Filename:=filetoopen, _
Origin:=65001, DataType:=xlDelimited, Comma:=True
End Sub
Происхождение:=65001 - это UTF-8. Запятая: верно для файлов.csv, распределенных в столбцах
Сохраните его в Personal.xlsb, чтобы он всегда был доступен. Персонализируйте панель инструментов Excel, добавив кнопку вызова макроса и открыв оттуда файлы. Вы можете добавить больше форматирования к макросу, например, автоподбор колонок, выравнивание и т. Д.
Просто для помощи пользователям, заинтересованным в открытии файла в Excel, которые добились этой темы, как я.
Я использовал мастер ниже, и он работал нормально для меня, импортируя файл UTF-8. Не прозрачно, но полезно, если у вас уже есть файл.
- Откройте Microsoft Excel 2007.
- Нажмите на пункт меню "Данные".
- Нажмите на значок "Из текста".
- Перейдите к местоположению файла, который вы хотите импортировать. Нажмите на имя файла, а затем нажмите кнопку "Импорт". На экране появится окно мастера импорта текста - шаг 1 или 3.
- Выберите тип файла, который лучше всего описывает ваши данные - с разделителями или фиксированной шириной.
- Выберите 65001: Unicode (UTF-8) из раскрывающегося списка рядом с источником файла.
- Нажмите кнопку "Далее", чтобы открыть окно "Мастер импорта текста" - шаг 2 или 3.
- Поставьте галочку рядом с разделителем, который использовался в файле, который вы хотите импортировать в Microsoft Excel 2007. Окно предварительного просмотра данных покажет вам, как будут выглядеть ваши данные на основе выбранного разделителя.
- Нажмите кнопку "Далее", чтобы открыть мастер импорта текста - шаг 3 из 3.
- Выберите подходящий формат данных для каждого столбца данных, которые вы хотите импортировать. У вас также есть возможность не импортировать один или несколько столбцов данных, если хотите.
- Нажмите кнопку Готово, чтобы завершить импорт данных в Microsoft Excel 2007.
Источник: https://www.itg.ias.edu/content/how-import-csv-file-uses-utf-8-character-encoding-0
Это старый вопрос, но он появляется в поиске сверху. После многих усилий я обнаружил, что добавление символов BOM в начале файла CSV помогает.
Я проинформировал его здесь: https://sites.google.com/site/ritechtips/home/the-multi-line-fields-csv-file-and-excel-import---ha
Это не совсем правильный вопрос, но поскольку я наткнулся на это, и вышеописанные решения не сработали для меня или у меня были требования, которые я не мог выполнить, вот еще один способ добавить спецификацию, когда у вас есть доступ к vim:
vim -e -s +"set bomb|set encoding=utf-8|wq" filename.csv
Да, это возможно. Как отмечалось ранее несколькими пользователями, кажется, что проблема с Excel в чтении правильной метки порядка байтов, когда файл закодирован в UTF-8. С UTF-16, похоже, нет проблем, поэтому он является эндемичным для UTF-8. Решением, которое я использую для этого, является добавление спецификации, ДВАЖДЫ. Для этого я дважды выполняю следующую команду sed:
sed -I '1s/^/\xef\xbb\xbf/' *.csv
где подстановочный знак можно заменить любым именем файла. Однако это приводит к мутации sep= в начале файла.csv. Файл.csv будет затем нормально открыт в Excel, но с дополнительной строкой с "sep=" в первой ячейке. "Sep =" также можно удалить в самом исходном файле.csv, но при открытии файла с помощью VBA необходимо указать разделитель:
Workbooks.Open(name, Format:=6, Delimiter:=";", Local:=True)
Формат 6 - это формат.csv. Установите для Local значение true, если в файле есть даты. Если для Local не установлено значение true, даты будут американизированы, что в некоторых случаях приведет к повреждению формата.csv.
Да, это возможно. При написании потока, создающего CSV, первое, что нужно сделать, это:
myStream.Write(Encoding.UTF8.GetPreamble(), 0, Encoding.UTF8.GetPreamble().Length)
Это мое рабочее решение:
vbFILEOPEN = "your_utf8_file.csv"
Workbooks.OpenText Filename:=vbFILEOPEN, DataType:=xlDelimited, Semicolon:=True, Local:=True, Origin:=65001
Ключ происхождения:=65001
Привет я использую рубин на рельсах для поколения CSV. В нашем приложении мы планируем использовать мультиязычность (I18n) и столкнулись с проблемой при просмотре содержимого I18n в CSV-файле Windows Excel.
Было хорошо с Linux (Ubuntu) и Mac.
Мы определили, что Windows Excel необходимо снова импортировать данные для просмотра реальных данных. При импорте мы получим больше опций для выбора набора символов.
Но это не может быть обучено для каждого пользователя, поэтому решение, которое мы ищем, должно быть открыто только двойным щелчком мыши.
Затем мы определили способ отображения данных в открытом режиме и в Windows Excel с помощью Aghuddleston Gist. Добавлено по ссылке.
Пример содержания I18n
В Mac и Linux
Шведский: Förnamn Английский: Имя
В винде
Шведский: Förnamn Английский: Имя
def user_information_report(report_file_path, user_id)
user = User.find(user_id)
I18n.locale = user.current_lang
open_mode = "w+:UTF-16LE:UTF-8"
bom = "\xEF\xBB\xBF"
body user, open_mode, bom
end
def headers
headers = [
"ID", "SDN ID",
I18n.t('sys_first_name'), I18n.t('sys_last_name'), I18n.t('sys_dob'),
I18n.t('sys_gender'), I18n.t('sys_email'), I18n.t('sys_address'),
I18n.t('sys_city'), I18n.t('sys_state'), I18n.t('sys_zip'),
I18n.t('sys_phone_number')
]
end
def body tenant, open_mode, bom
File.open(report_file_path, open_mode) do |f|
csv_file = CSV.generate(col_sep: "\t") do |csv|
csv << headers
tenant.patients.find_each(batch_size: 10) do |patient|
csv << [
patient.id, patient.patientid,
patient.first_name, patient.last_name, "#{patient.dob}",
"#{translate_gender(patient.gender)}", patient.email, "#{patient.address_1.to_s} #{patient.address_2.to_s}",
"#{patient.city}", "#{patient.state}", "#{patient.zip}",
"#{patient.phone_number}"
]
end
end
f.write bom
f.write(csv_file)
end
end
Важные вещи, на которые следует обратить внимание, это открытый режим и бомба
open_mode = "w +: UTF-16LE: UTF-8"
bom = "\ xEF \ xBB \ xBF"
Перед написанием CSV вставьте спецификацию
напиши бом
f.write (csv_file)
Windows и Mac
Файл можно открыть напрямую двойным щелчком мыши.
Linux (Ubuntu)
При открытии файла запросите параметры разделителя -> выберите "TAB"
В Python используйтеencoding=utf-8-sig
это имя Python для UTF-8 со спецификацией. Толькоutf-8
не будет обработан Excel или другим программным обеспечением Microsoft. Из https://docs.python.org/3/library/codecs.html :
Чтобы повысить надежность определения кодировки UTF-8, Microsoft изобрела вариант UTF-8 (который Python называет «utf-8-sig»).
См. также В чем разница между utf-8 и utf-8-sig?
Используя стандартную библиотеку python csv , это будет:
with open('some.csv', 'w', newline='', encoding='utf-8-sig') as f:
writer = csv.writer(f)
writer.writerows(someiterable)
Он также работает с другими библиотеками, такими как pandas :
df.to_csv('some.csv', encoding='utf-8-sig')
- Загрузите и установите LibreOffice Calc
- Откройте файл CSV по вашему выбору в LibreOffice Calc
- Слава Богу, что появился мастер импорта текста...
- ... выберите разделитель и параметры кодировки символов
- Выберите полученные данные в Calc и скопируйте их в Excel
Нашел решение для ASP.NET Core для загрузки CSV как UTF8 с POM:
byte[] csvBytes = Encoding.Default.GetBytes(csvString);
UTF8Encoding utf8 = new UTF8Encoding(true);
byte[] bom = utf8.GetPreamble();
var result = bom.Concat(csvBytes).ToArray();
return new FileContentResult(result, MediaTypeHeaderValue.Parse("text/csv; charset=utf-8"));
Excel распознает загруженный файл CSV как UTF8.
15 лет спустя я наконец нашел решение: написать CSV в форматеUTF-16-LE
безBOM
, и он будет работать в Excel 2007+.
Пример с Python:
import csv
with open('test.csv', "w", encoding="utf-16-le", newline='') as csvfile:
w = csv.writer(csvfile, delimiter=';')
w.writerow(["abc", "def"])
w.writerow(["été", "hiver"])
Выходной файл CSV можно открыть непосредственно в Excel и:
- никаких проблем с акцентами
- разделители будут автоматически разбиты на несколько столбцов
Я столкнулся с той же проблемой несколько дней назад и не смог найти решения, потому что не могу использовать import from csv
особенность, потому что она заставляет все оформлять как строку.
Мое решение заключалось в том, чтобы сначала открыть файл с помощью notpad++ и change the encode to ASCII
. Затем просто открыл файл в Excel, и он работал, как ожидалось.
Рабочее решение для офиса 365
- сохранить в
UTF-16
(нет LE, BE) - использовать разделитель
\t
Код на PHP
$header = ['číslo', 'vytvořeno', 'ěščřžýáíé'];
$fileName = 'excel365.csv';
$fp = fopen($fileName, 'w');
fputcsv($fp, $header, "\t");
fclose($fp);
$handle = fopen($fileName, "r");
$contents = fread($handle, filesize($fileName));
$contents = iconv('UTF-8', 'UTF-16', $contents);
fclose($handle);
$handle = fopen($fileName, "w");
fwrite($handle, $contents);
fclose($handle);
Я перепробовал все, что мог найти в этой теме и тому подобное, ничего не получалось полностью. Тем не менее, импортирование в листы Google и просто загрузка в формате csv работали как шарм. Попробуйте, если вы придете к моему разочарованию.
Это старый вопрос, но я только что столкнулся с аналогичной проблемой, и решение может помочь другим:
Была такая же проблема, когда записывать текстовые данные в формате CSV в файл, а затем открывать получившийся файл.csv в Excel, чтобы сдвинуть весь текст в один столбец. Прочитав приведенные выше ответы, я попробовал следующее, что, похоже, решило проблему.
Примените кодировку UTF-8 при создании StreamWriter. Вот и все.
Пример:
using (StreamWriter output = new StreamWriter(outputFileName, false, Encoding.UTF8, 2 << 22)) {
/* ... do stuff .... */
output.Close();
}
Я сделал кардинальное изменение: вместо предоставления пользователям .csv я предоставляю .xlsx :)
Поскольку я создавал файл CSV программным путем и поскольку этими файлами манипулируют только люди, нет причин продолжать использовать простой формат .csv (более подходящий для анализа). Примечание
.xlsx
файлы широко поддерживаются (и не только в Excel).
Мне не пришлось менять всю логику, я просто взял свой предыдущий сценарий генерации CSV и добавил библиотеку Excel для преобразования CSV в XLSX в несколько строк. Вы должны быть в состоянии сделать это независимо от языка :)
В идеале я бы предпочел обойтись без продуктов Microsoft, но иногда приходится просто сидеть на «стандарте».
Просто поделитесь всеобъемлющей функцией, которая может облегчить вашу жизнь при работе с CSV-файлами... обратите внимание на последний аргумент функции в связи с этой темой.
function array2csv($data, $file = '', $download = true, $mode = 'w+', $delimiter = ',', $enclosure = '"', $escape_char = "\\", $addUnicodeBom = false)
{
$return = false;
if ($file == '') {
$f = fopen('php://memory', 'r+');
} else {
$f = fopen($file, $mode);
}
if ($addUnicodeBom) {
$utf8_with_bom = chr(239) . chr(187) . chr(191);
fwrite($f, $utf8_with_bom);
}
foreach ($data as $line => $item) {
fputcsv($f, $item, $delimiter, $enclosure, $escape_char);
}
rewind($f);
if ($download == true) {
$return = stream_get_contents($f);
} else {
$return = true;
}
return $return;
}