C #, Excel + CSV: как получить правильную кодировку? - PullRequest
12 голосов
/ 27 июля 2010

Я уже давно пробую это, но не могу понять. Я пытаюсь экспортировать данные в 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;

Ответы [ 7 ]

8 голосов
/ 27 июля 2010

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

7 голосов
/ 01 августа 2012

Это сработало идеально для меня:

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)

5 голосов
/ 24 августа 2010

попробуйте следующее:

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.

3 голосов
/ 27 июля 2010

"ANSI как UTF8" (WTF?)

NotePad ++, вероятно, правильно. Кодировка UTF8 (т. Е. Правильный заголовок Unicode), но содержит только данные ANSI (т. Е. Не кодируется в правильном UTF8-формате, что означает два байта).

Или: это наоборот. Это ANSI (без спецификации заголовка файла), но кодировка отдельных символов является или выглядит как UTF8. Это объяснило бы, что другие символы расширяются более чем на один другой символ. Вы можете исправить это, заставив файл читать как Unicode.

Если возможно опубликовать (частично) ваш CSV, мы можем помочь исправить его у источника.

Редактировать

Теперь, когда мы увидели ваш код: вы можете удалить StreamWriter и заменить его на TextWriter? Кроме того, удалить кодировку вручную спецификации, это не является необходимым. При создании TextWriter вы можете указать кодировку (не используйте ASCII, попробуйте UTF8).

2 голосов
/ 15 июля 2014

Тревор Жермен помог мне сохранить в правильном кодированном формате

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);
}
2 голосов
/ 27 июля 2010

Я бы предложил вам открыть текстовый файл в шестнадцатеричном редакторе и посмотреть, что это на самом деле.Спецификация для UTF-16 - 0xFEFF, которую код записи, по-видимому, записывает в поток - но остальная часть записи не указывает используемую кодировку - она ​​будет использовать кодировку по умолчанию StreamWriter, которая является UTF-8,Похоже, что происходит смешивание кодировок.

Когда вы открываете файл в шестнадцатеричном представлении, если вы видите много символов 0x00 между символами, вы работаете с UTF-16, то есть Encoding.Unicodeв C #.Если между символами нет 0x00, кодировка, вероятно, будет UTF-8.

Если в последнем случае просто исправьте спецификацию на EF BB BF, а не FE FF, и нормально читайте с помощью UTF-8кодирование.

0 голосов
/ 21 марта 2016

Для моего сценария, использующего StreamWriter, я обнаружил, что передача кодировки UTF8 в StreamWriter позволила Excel превратить файл в правильную кодировку

См. Этот ответ для более подробной информации: https://stackoverflow.com/a/22306937/999048

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...