Подтвердить что ты не робот

С#, 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;
4b9b3361

Ответ 1

Это решение записано как исправление для Java-приложения, но вы должны иметь возможность сделать что-то подобное на С#. Вы также можете посмотреть документацию в классе StreamWriter, в примечаниях это относится к значению байтового заказа (BOM).

Ответ 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/...