在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总是把引号周围的每个单元格?如果不是,我该如何解决这个问题?

在c#中,可以剪贴板.GetData将强制在每个CSV值周围输出引号

最简单的方法是使用数据绑定并将字符串写入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());
    }