С#, Excel + csv: как получить правильную кодировку?
Я уже давно это пробовал, но не могу понять. Я пытаюсь экспортировать данные в Excel через файл *.csv. До сих пор он отлично работает, но у меня есть некоторые проблемы с кодировкой при открытии файлов в Excel.
(исходная строка слева, результат EXCEL справа):
Messwert(µm / m) ==> Messwert(µm / m)
Dümme Mässöng ==> Dümme Mässöng
Notepad ++ сообщает мне, что файл закодирован "ANSI as UTF8" (WTF?)
Итак, вот несколько способов, по которым я пытался получить действительный результат:
очевидная реализация:
tWriter.Write(";Messwert(µm /m)");
более сложный (возможно, дюжина или более комбинаций кодировок:)
tWriter.Write(Encoding.Default.GetString(Encoding.Unicode.GetBytes(";Messwert(µm /m)")));
tWriter.Write(Encoding.ASCII.GetString(Encoding.Unicode.GetBytes(";Messwert(µm /m)")));
и т.д.
Целый исходный код для метода создания данных:
MemoryStream tStream = new MemoryStream();
StreamWriter tWriter = new StreamWriter(tStream);
tWriter.Write("\uFEFF");
tWriter.WriteLine(string.Format("{0}", aMeasurement.Name));
tWriter.WriteLine(aMeasurement.Comment);
tWriter.WriteLine();
tWriter.WriteLine("Zeit in Minuten;Messwert(µm / m)");
TimeSpan tSpan;
foreach (IMeasuringPoint tPoint in aMeasurement)
{
tSpan = new TimeSpan(tPoint.Time - aMeasurement[0].Time);
tWriter.WriteLine(string.Format("{0};{1};", (int)tSpan.TotalMinutes, getMPString(tPoint)));
}
tWriter.Flush();
return tStream;
Сгенерированный файл CSV:
Dümme Mössäng
Testmessung die erste
Zeit in Minuten;Messwert(µm / m)
0;-703;
0;-381;
1;1039;
1;1045;
2;1457;
2;1045;
Ответы
Ответ 1
Это решение записано как исправление для Java-приложения, но вы должны иметь возможность сделать что-то подобное на С#. Вы также можете посмотреть документацию в классе StreamWriter, в примечаниях это относится к значению байтового заказа (BOM).
Ответ 2
Это сработало отлично для меня:
private const int WIN_1252_CP = 1252; // Windows ANSI codepage 1252
this._writer = new StreamWriter(fileName, false, Encoding.GetEncoding(WIN_1252_CP));
Проблемы с кодировкой CSV (Microsoft Excel)
Ответ 3
попробуйте следующее:
using (var sw = File.Create(Path.Combine(txtPath.Text, "UTF8.csv")))
{
var preamble = Encoding.UTF8.GetPreamble();
sw.Write(preamble, 0, preamble.Length);
var data = Encoding.UTF8.GetBytes("懘荧,\"Hello\",text");
sw.Write(data, 0, data.Length);
}
Он записывает правильную преамбулу UTF8 в файл перед записью CSV с кодировкой UTF8.
Ответ 4
"ANSI as UTF8" (WTF?)
NotePad ++, вероятно, правильный. Кодировка UTF8 (то есть правильный заголовок Юникода), но содержит только данные ANSI (то есть, é не кодируется правильным способом UTF8, что означает два байта).
Или: это наоборот. Это ANSI (без спецификации заголовка файла), но кодировка отдельных символов является или выглядит UTF8. Это объясняет, что ü и другие символы расширяются более чем одним другим персонажем. Вы можете исправить это, заставив файл читать как Unicode.
Если возможно разместить (часть) вашего CSV, мы можем помочь исправить его в источнике.
Изменить
Теперь, когда мы увидели ваш код: вы можете удалить StreamWriter и заменить его TextWriter? Кроме того, удалите ручную кодировку спецификации, это необязательно. Когда вы создаете TextWriter, вы можете указать кодировку (не используйте ASCII, попробуйте UTF8).
Ответ 5
Я предлагаю вам открыть текстовый файл в шестнадцатеричном редакторе и посмотреть, что это на самом деле. Спецификация для UTF-16 равна 0xFEFF, которая, по-видимому, записывает код записи в поток, но в остальной части записи не указывается кодировка для использования - она будет использовать кодировку по умолчанию StreamWriter, которая является UTF-8, Похоже, что существует сочетание кодировок.
Когда вы открываете файл в шестнадцатеричном представлении, если вы видите много 0x00 между символами, вы работаете с UTF-16, который является Encoding.Unicode в С#. Если между символами нет 0x00, кодировка, вероятно, UTF-8.
Если последний случай, просто исправьте спецификацию EF BB BF
, а не FE FF
, и обычно читайте с кодировкой UTF-8.
Ответ 6
Тревор Жермен помог мне сохранить в правильном кодированном формате
using (var sw = File.Create(Path.Combine(txtPath.Text, "UTF8.csv")))
{
var preamble = Encoding.UTF8.GetPreamble();
sw.Write(preamble, 0, preamble.Length);
var data = Encoding.UTF8.GetBytes("懘荧,\"Hello\",text");
sw.Write(data, 0, data.Length);
}
Ответ 7
В моем сценарии с использованием StreamWriter я явно передал кодировку UTF8 в excel для StreamWriter, чтобы прочитать файл, используя правильную кодировку.
См. этот ответ для получения дополнительной информации:
fooobar.com/info/426529/...