Cómo pegar datos CSV al Portapapeles de Windows con C#
clipboard paste (3)
Lo que intento lograr
- Mi aplicación genera algunos datos tabulares
- Quiero que el usuario pueda iniciar Excel y hacer clic en "pegar" para colocar los datos como celdas en Excel
- Windows acepta un formato llamado "CommaSeparatedValue" que se usa con sus API, por lo que esto parece posible
- Poner texto sin formato en el portapapeles funciona, pero tratar de usar este formato no
- NOTA: puedo recuperar correctamente los datos CSV del portapapeles, mi problema es pegar datos CSV en el portapapeles.
Lo que he intentado no funciona
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",
);
En ambos casos, se coloca algo en el portapapeles, pero cuando se pega en Excel, aparece como una celda del texto de garbarge: "-§žý; pC|yVk²û"
Actualización 1: solución usando SetText ()
Como la respuesta de BFree muestra SetText con TextDataFormat sirve como una solución
System.Windows.Forms.Clipboard.SetText(
"1/t2/t3/t4/n5/t6/t7/t8",
System.Windows.Forms.TextDataFormat.Text
);
He intentado esto y confirmo que ahora pegar en Excel y Word funciona correctamente. En cada caso, se pega como una tabla con celdas en lugar de texto sin formato.
Todavía curioso por qué CommaSeparatedValue no está funcionando.
.NET Framework coloca DataFormats.CommaSeparatedValue
en el portapapeles como texto Unicode. Pero como se menciona en http://www.syncfusion.com/faq/windowsforms/faq_c98c.aspx#q899q , Excel espera que los datos CSV sean una secuencia de memoria UTF-8 (es difícil decir si .NET o Excel tienen la culpa por la incompatibilidad).
La solución que he encontrado en mi propia aplicación es colocar dos versiones de los datos tabulares en el portapapeles simultáneamente como texto delimitado por tabuladores y como una secuencia de memoria CSV. Esto permite que la aplicación de destino adquiera los datos en su formato preferido. Notepad y Excel prefieren el texto delimitado por tabuladores, pero puede obligar a Excel a tomar los datos CSV mediante el comando Pegado especial ... para realizar pruebas.
Aquí hay un código de ejemplo (tenga en cuenta que los equivalentes de WinForms de los espacios de nombres de WPF se usan aquí):
// 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);
He tenido éxito al pegar en Excel usando / t (vea la respuesta de BFree) como separadores de columnas y / n como separadores de filas.
Usa pestañas en lugar de comas. es decir:
Clipboard.SetText("1/t2/t3/t4/t3/t2/t3/t4", TextDataFormat.Text);
Acabo de probar esto por mí mismo, y funcionó para mí.