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

Получите CSV-данные из буфера обмена (вставленные из Excel), содержащие символы с акцентом

СЦЕНАРИЙ

  • Мои пользователи будут копировать ячейки из Excel (таким образом, помещая их в буфер обмена).
  • И мое приложение будет извлекать эти ячейки из буфера обмена

ПРОБЛЕМА

  • Мой код извлекает формат CSV из буфера обмена
  • Однако, если исходный текст в Excel содержит символы типа ä (a с umlaut), то извлеченная строка CSV не имеет правильных символов (ä заканчивается тем, что отображается как "квадрат" для меня).
  • Для сравнения, если мой код извлекает текстовый формат Unicode из буфера обмена, все работает отлично: символ сохраняется в строке, полученной из буфера обмена

ИСТОЧНИК КОДА - ОРИГИНАЛ - С ПРОБЛЕМА

[STAThread]
static void Main(string[] args)
{
    var fmt_csv = System.Windows.Forms.DataFormats.CommaSeparatedValue;

    // read the CSV
    var dataobject = System.Windows.Forms.Clipboard.GetDataObject();
    var stream = (System.IO.Stream)dataobject.GetData(fmt_csv);
    var enc = new System.Text.UTF8Encoding();
    var reader = new System.IO.StreamReader(stream,enc);
    string data_csv = reader.ReadToEnd();

    // read the unicode string
    string data_string = System.Windows.Forms.Clipboard.GetText();



}

РЕЗУЛЬТАТЫ ПРИ ИСПОЛЬЗОВАНИИ КОДА ОБРАЗЦОВ

  • Действия Repro: введите текст в Excel (я использовал слово "doppelgänger" плюс некоторые цифры) и просто нажмите Ctrl-C, чтобы скопировать его в буфер обмена, а затем запустите код выше.
  • data_csv устанавливается в "doppelg nger, 1\r\n2,3\r\n\0"
  • data_string имеет значение "doppelgänger\t1\r\n2\t3\r\n"

Вопрос

  • Что я могу сделать, чтобы получить правильные символы?

КОММЕНТАРИИ

  • Да, я знаю, что мог бы решить эту проблему, используя текст Unicode. Но я действительно хочу понять, что происходит с CSV
  • использование или отсутствие использования кодировки UTF-8 при извлечении потока не влияет на результаты

ОТВЕТ

После просмотра комментариев и обращая пристальное внимание на то, что Excel помещал в буфер обмена для CSV, казалось разумным, что Excel может размещать содержимое с использованием "устаревшей" кодировки вместо UTF-8. Поэтому я попытался использовать кодировку Windows 1252 в качестве кодировки, и она сработала. См. Код ниже

ИСТОЧНИЧНЫЙ КОД - С ОТВЕТОМ

[STAThread]
static void Main(string[] args)
{
    var fmt_csv = System.Windows.Forms.DataFormats.CommaSeparatedValue;

    //read the CSV
    var dataobject = System.Windows.Forms.Clipboard.GetDataObject();
    var stream = (System.IO.Stream)dataobject.GetData(fmt_csv);
    var enc = System.Text.Encoding.GetEncoding(1252);
    var reader = new System.IO.StreamReader(stream,enc);
    string data_csv= reader.ReadToEnd();

    //read the Unicode String
    string data_string = System.Windows.Forms.Clipboard.GetText();
}
4b9b3361

Ответ 1

Excel хранит строку в буфере обмена, используя кодировку символов Unicode. Причина, по которой вы получаете квадрат, когда пытаетесь прочитать строку в ANSI, заключается в том, что для этого символа в вашей кодовой странице ANSI нет представления. Вы должны просто использовать Unicode. Если вы собираетесь решать проблемы локализации, то ANSI просто больше проблем, чем того стоит.

Изменить: Joel Spolsky написал отличное введение в кодировки символов, которые, безусловно, стоит проверить: Абсолютное минимальное количество всех программ Разработчик абсолютно, положительно должен знать о Unicode и наборах символов (без отговорок!)

Ответ 2

Ваша кодировка потока как UTF8 не работает. Байты для умлаут преобразуются в символ Unicode с заменяющим символом.

Вместо этого просто просмотрите данные потока без каких-либо дополнительных инструкций по кодированию. Данные будут в некотором формате, используемом Excel. Вы должны быть в состоянии сказать, глядя на байт (ы), где находится неавтоматический. Затем вы сможете преобразовать его в UTF-8.

В худшем случае, если CSV Formatter выбрасывает все, что не является Ascii. В этом случае вы можете написать собственный формат данных.

В некоторых случаях люди Excel полагают, что CSV означает только Ascii. См. http://www.tech-archive.net/Archive/Excel/microsoft.public.excel.misc/2008-07/msg02270.html