Как вставить данные CSV в буфер обмена Windows с помощью C # - PullRequest
28 голосов
/ 01 декабря 2008

Чего я пытаюсь достичь

  • Мое приложение генерирует некоторые табличные данные
  • Я хочу, чтобы пользователь мог запускать Excel и нажимать «вставить», чтобы поместить данные в виде ячеек в Excel
  • Windows принимает формат CommaSeparatedValue, который используется с его API, так что это кажется возможным
  • Помещение необработанного текста в буфер обмена работает, но попытка использовать этот формат не
  • ПРИМЕЧАНИЕ. Я могу правильно извлечь данные CSV из буфера обмена, моя проблема заключается в вставке данных CSV в буфер обмена.

То, что я пробовал, не работает

Clipboard.SetText ()

System.Windows.Forms.Clipboard.SetText(  
  "1,2,3,4\n5,6,7,8", 
  System.Windows.Forms.TextDataFormat.CommaSeparatedValue
  );

Clipboard.setData ()

System.Windows.Forms.Clipboard.SetData(
  System.Windows.Forms.DataFormats.CommaSeparatedValue,
  "1,2,3,4\n5,6,7,8", 
  );

В обоих случаях что-то помещается в буфер обмена, но при вставке в Excel оно отображается как одна ячейка текста garbarge: "–§žý; pC¦yVk²ˆû"

Обновление 1: временное решение с использованием SetText ()

Как показывает ответ BFree, SetText с TextDataFormat служит в качестве обходного пути

System.Windows.Forms.Clipboard.SetText(  
  "1\t2\t3\t4\n5\t6\t7\t8", 
  System.Windows.Forms.TextDataFormat.Text
  );

Я пробовал это и подтверждаю, что теперь вставка в Excel и Word работает правильно. В каждом случае он вставляется в виде таблицы с ячейками вместо открытого текста.

Все еще любопытно, почему CommaSeparatedValue не работает.

Ответы [ 3 ]

34 голосов
/ 15 декабря 2008

.NET Framework помещает DataFormats.CommaSeparatedValue в буфер обмена как текст Unicode. Но, как упоминалось в http://www.syncfusion.com/faq/windowsforms/faq_c98c.aspx#q899q, Excel ожидает, что данные CSV будут потоком памяти UTF-8 (сложно сказать, виноваты ли .NET или Excel из-за несовместимости).

Решение, которое я нашел в своем собственном приложении, заключается в том, чтобы поместить две версии табличных данных в буфер обмена одновременно в виде текста с разделителями табуляции и в виде потока памяти CSV. Это позволяет целевому приложению получать данные в своем предпочтительном формате. Notepad и Excel предпочитают текст с разделителями табуляции, но вы можете заставить Excel захватывать данные CSV с помощью команды Paste Special ... для тестирования.

Вот пример кода (обратите внимание, что здесь используются WinForms-эквиваленты из пространств имен WPF):

// Generate both tab-delimited and CSV strings.
string tabbedText = //...
string csvText = //...

// Create the container object that will hold both versions of the data.
var dataObject = new System.Windows.DataObject();

// Add tab-delimited text to the container object as is.
dataObject.SetText(tabbedText);

// Convert the CSV text to a UTF-8 byte stream before adding it to the container object.
var bytes = System.Text.Encoding.UTF8.GetBytes(csvText);
var stream = new System.IO.MemoryStream(bytes);
dataObject.SetData(System.Windows.DataFormats.CommaSeparatedValue, stream);

// Copy the container object to the clipboard.
System.Windows.Clipboard.SetDataObject(dataObject, true);
6 голосов
/ 01 декабря 2008

Используйте вкладки вместо запятых. то есть:

Clipboard.SetText("1\t2\t3\t4\t3\t2\t3\t4", TextDataFormat.Text);

Только что сам проверил, и у меня это сработало.

3 голосов
/ 01 декабря 2008

Я успешно вставил в Excel, используя \ t (см. Ответ BFree) в качестве разделителей столбцов и \ n в качестве разделителей строк.

...