MosesTheHoly
MosesTheHoly

Reputation: 39

Exporting DataGrid to CSV without a GUI in WPF

I have an application that runs with and without a GUI depending on the user. I need it to export the DataGrid as a CSV file, heres the code:

// Copy contents of datagrid to clipboard, including header.
mainDataGrid.SelectAllCells();
mainDataGrid.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
ApplicationCommands.Copy.Execute(null, mainDataGrid);

string result = (string)Clipboard.GetData(DataFormats.CommaSeparatedValue);

This works fine with the GUI. The problem happens when I don't have a GUI, I think this is because the clipboard can't copy something that isn't there. Is there a different way to export it or is there a way to set the clipboards data instead of executing a copy command?

Upvotes: 0

Views: 1928

Answers (2)

BerryAllan
BerryAllan

Reputation: 26

In order to "copy something that isn't there", you'll need to use the underlying data object that is your DataGrid's ItemsSource.

If your DataGrid's ItemsSource is a DataTable, this method, analogous to MosesTheHoly's, will return a CSV string, but in a simpler manner.

public string GetCSVFromDataTabe(DataTable datatable)
{
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.Append(string.Join(",", dt.Columns.ToList<DataColumn>().Select(column => column.ColumnName).ToList()) + "\n");
    dataTable.Rows.ToList<DataRow>().ForEach(row => sb.Append(string.Join(",", row.ItemArray) + "\n"));
    return stringBuilder.ToString();
}

That should do it. Fairly concise, in my opinion. Now, just write that string to whatever file you need.

Upvotes: 1

MosesTheHoly
MosesTheHoly

Reputation: 39

Alright, the code could probably be shortened, but this is the way I did it. I created a function that takes in a datatable and returns a CSV string.

private void SaveToCSV() {
    DataTable dt = new DataTable();
    dt = ((DataView)mainDataGrid.ItemsSource).ToTable();

    string result = WriteDataTable(dt);

    // The File.Create().Close() is so it closes the filestream after it creates it.
    if (!File.Exists(CSVFilePath)) {
        File.Create(CSVFilePath).Close();
    }
    File.AppendAllText(CSVFilePath, result, UnicodeEncoding.UTF8);
}

private string WriteDataTable(DataTable dataTable) {
    string output = "";

    // Need to get the last column so I know when to add a new line instead of comma.
    string lastColumnName = dataTable.Columns[dataTable.Columns.Count - 1].ColumnName;

    // Get the headers from the datatable.
    foreach (DataColumn column in dataTable.Columns) {
        if (lastColumnName != column.ColumnName) {
            output += (column.ColumnName.ToString() + ",");
        }
        else {
            output += (column.ColumnName.ToString() + "\n");
        }
    }
    // Get the actual data from the datatable.
    foreach (DataRow row in dataTable.Rows) {
        foreach (DataColumn column in dataTable.Columns) {
            if (lastColumnName != column.ColumnName) {
                output += (row[column].ToString() + ",");
            }
            else {
                output += (row[column].ToString() + "\n");
            }
        }
    }
    return output;
}

Upvotes: 0

Related Questions