Friday, August 13, 2010

Extension method to export a Silverlight Datagrid to CSV

Well, I couldn't figure out how to export it as an excel doc, but CSV is just as good...right? (Of course not, but it's good enough.)

This is an extension method, so you'd have to call it with dataGrid1.Export();

public static class DataGridExtensions
{
    public static void Export(this DataGrid dg)
    {
        SaveExportedGrid(ExportDataGrid(true, dg));
    }

    public static void Export(this DataGrid dg, bool withHeaders)
    {
        SaveExportedGrid(ExportDataGrid(withHeaders, dg));
    }

    private static void SaveExportedGrid(string data)
    {
        SaveFileDialog sfd = new SaveFileDialog() { DefaultExt = "csv", Filter = "CSV Files (*.csv)|*.csv|All Files (*.*)|*.*", FilterIndex = 1 };
        if (sfd.ShowDialog() ?? false)
        {
            using (StreamWriter sr = new StreamWriter(sfd.OpenFile()))
                sr.Write(data);
        }
    }

    private static string ExportDataGrid(bool withHeaders, DataGrid grid)
    {
        string colPath;
        System.Reflection.PropertyInfo propInfo;
        System.Windows.Data.Binding binding;
        System.Text.StringBuilder strBuilder = new System.Text.StringBuilder();
        System.Collections.IList source = (grid.ItemsSource as System.Collections.IList);
        if (source == null)
            return "";

        List<string> headers = new List<string>();
        grid.Columns.ToList().ForEach(col =>
        {
            if (col is DataGridBoundColumn)
            {
                headers.Add(FormatCSVField(col.Header.ToString()));
            }
        });
        strBuilder
        .Append(String.Join(",", headers.ToArray()))
        .Append("\r\n");

        foreach (Object data in source)
        {
            List<string> csvRow = new List<string>();
            foreach (DataGridColumn col in grid.Columns)
            {
                if (col is DataGridBoundColumn)
                {
                    binding = (col as DataGridBoundColumn).Binding;
                    colPath = binding.Path.Path;
                    propInfo = data.GetType().GetProperty(colPath);
                    if (propInfo != null)
                    {
                        csvRow.Add(FormatCSVField(propInfo.GetValue(data, null).ToString()));
                    }
                }
            }
            strBuilder
                .Append(String.Join(",", csvRow.ToArray()))
                .Append("\r\n");
        }

        return strBuilder.ToString();
    }

    private static string FormatCSVField(string data)
    {
        return String.Format("\"{0}\"",
            data.Replace("\"", "\"\"\"")
            .Replace("\n", "")
            .Replace("\r", "")
            );
    }
}

No comments:

Post a Comment

Speak your mind.