在c#中,可以剪贴板.GetData将强制在每个CSV值周围输出引号
本文关键字:CSV 周围 输出 GetData 剪贴板 | 更新日期: 2023-09-27 18:07:36
在c#中,我使用以下代码将数据从WPF DataGrid
复制到剪贴板,然后从剪贴板复制到CSV:
var originalSelectionMode = dataGrid.SelectionMode;
dataGrid.SelectionMode = DataGridSelectionMode.Extended;
dataGrid.SelectAllCells();
dataGrid.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
ApplicationCommands.Copy.Execute(null, dataGrid);
dataGrid.UnselectAllCells();
// this is the line that's not working quite right:
var text = (string)Clipboard.GetData(DataFormats.CommaSeparatedValue);
Clipboard.Clear();
dataGrid.SelectionMode = originalSelectionMode;
File.WriteAllText(fullPathToFile, text);
这段代码在大多数情况下都可以工作,但是当其中一个单元格中有多行文本时就会出现问题。假设你有这样一个网格中的数据:
A |B |C
-------------------
A1 |B1 |C1a,C2b
-------------------
A2 |B2 |C2a
| |C2b
-------------------
Clipboard.GetData
函数似乎只在单元格内容中有逗号或双引号字符的情况下,在单元格内容周围插入双引号,但如果您在那里有换行符,则不会自动这样做,因此上面网格的输出看起来像这样:
A,B,C
A1,B1,"C1a,C1b"
A2,B2,C2a
C2b
请注意,它在单元格C1周围加了引号,而不是单元格C2。
是否有一种方法,我可以强迫Clipboard.GetData
总是把引号周围的每个单元格?如果不是,我该如何解决这个问题?
最简单的方法是使用数据绑定并将字符串写入csv。我已经创建了一个示例类,可以绑定到DataGrid,并允许创建/编辑新行(如果需要,您可以在该类上添加通知):
public class Data
{
public Data()
{
}
public Data(string col1, string col2, string col3)
{
Col1 = col1;
Col2 = col2;
Col3 = col3;
}
public string Col1 { get; set; }
public string Col2 { get; set; }
public string Col3 { get; set; }
}
现在我重写数据网格的Copy命令来控制自定义复制:
this.DataGrid.CommandBindings.Add(new CommandBinding(ApplicationCommands.Copy,
new ExecutedRoutedEventHandler(CopyClicked)));
在CopyClicked中,我们使用data ViewModel绑定类创建数据:
private void CopyClicked(object sender, ExecutedRoutedEventArgs e)
{
var stringBuilder = new StringBuilder();
IList l = this.DataGrid.SelectedItems;
foreach (Data data in l)
{
stringBuilder.Append("'"" + data.Col1 +"'",");
stringBuilder.Append("'"" + data.Col2 + "'",");
stringBuilder.Append("'"" + data.Col3 + "'"");
stringBuilder.AppendLine();
}
//Write to a file or straight to clipboard etc
Debug.WriteLine(stringBuilder.ToString());
}