Click here to Skip to main content
Click here to Skip to main content

Export Silverlight DataGrid to Excel XML/CSV

By , 1 Dec 2009
 

Introduction

There are several reasons for the end user to export data from an application into an Excel compatible format (mostly for further analysis/usage or data). This article explains how to include data export capability to Silverlight DataGrid.

Background

I am working on migrating some ASP.NET code to a Silverlight application. One of the features that I felt lacking in Silverlight is the ability to export the contents of a DataGrid to the end user. To address this issue, I created an extension for DataGrid control. When the attached file (DataGridExtensions.cs) is included in a project, the "Export" extension is automatically made available to all the DataGrid controls used in the project.

Using the code

This module exposes two methods:

  • Export (this DataGrid dg) - extends the DataGrid control by providing the export functionality.
  • ExportDataGrid (DataGrid dGrid) - this method is internally called by the "Export" DataGrid extension. However, this method can be directly called too.
public static void Export(this DataGrid dg)
{
    ExportDataGrid(dg);
}
public static void ExportDataGrid(DataGrid dGrid)
{
    SaveFileDialog objSFD = new SaveFileDialog() { DefaultExt = "csv", 
        Filter = "CSV Files (*.csv)|*.csv|Excel XML (*.xml)|*.xml|All files (*.*)|*.*", 
        FilterIndex = 1 };
    if (objSFD.ShowDialog() == true)
    {
        string strFormat = 
          objSFD.SafeFileName.Substring(objSFD.SafeFileName.IndexOf('.') + 1).ToUpper();
        StringBuilder strBuilder = new StringBuilder();
        if (dGrid.ItemsSource == null) return;
        List<string> lstFields = new List<string>();
        if (dGrid.HeadersVisibility == DataGridHeadersVisibility.Column || 
            dGrid.HeadersVisibility == DataGridHeadersVisibility.All)
        {
            foreach (DataGridColumn dgcol in dGrid.Columns)
                lstFields.Add(FormatField(dgcol.Header.ToString(), strFormat));
            BuildStringOfRow(strBuilder, lstFields, strFormat);
        }
        foreach (object data in dGrid.ItemsSource)
        {
            lstFields.Clear();
            foreach (DataGridColumn col in dGrid.Columns)
            {
                string strValue = "";                    
                Binding objBinding = null;
                if (col is DataGridBoundColumn)
                    objBinding = (col as DataGridBoundColumn).Binding;
                if (col is DataGridTemplateColumn)
                {
                    //This is a template column...
                    //    let us see the underlying dependency object
                    DependencyObject objDO = 
                      (col as DataGridTemplateColumn).CellTemplate.LoadContent();
                    FrameworkElement oFE = (FrameworkElement)objDO;
                    FieldInfo oFI = oFE.GetType().GetField("TextProperty");
                    if (oFI != null)
                    {
                        if (oFI.GetValue(null) != null)
                        {
                            if (oFE.GetBindingExpression(
                                   (DependencyProperty)oFI.GetValue(null)) != null)
                                objBinding = 
                                  oFE.GetBindingExpression(
                                  (DependencyProperty)oFI.GetValue(null)).ParentBinding;
                        }
                    }
                }
                if (objBinding != null)
                {
                    if (objBinding.Path.Path != "")
                    {
                        PropertyInfo pi = data.GetType().GetProperty(objBinding.Path.Path);
                        if (pi != null) strValue = pi.GetValue(data, null).ToString();
                    }
                    if (objBinding.Converter != null)
                    {
                        if (strValue != "")
                            strValue = objBinding.Converter.Convert(strValue, 
                              typeof(string), objBinding.ConverterParameter, 
                              objBinding.ConverterCulture).ToString();
                        else
                            strValue = objBinding.Converter.Convert(data, 
                              typeof(string), objBinding.ConverterParameter, 
                              objBinding.ConverterCulture).ToString();
                    }
                }
                lstFields.Add(FormatField(strValue,strFormat));
            }
            BuildStringOfRow(strBuilder, lstFields, strFormat);
        }
        StreamWriter sw = new StreamWriter(objSFD.OpenFile());
        if (strFormat == "XML")
        {
            //Let us write the headers for the Excel XML
            sw.WriteLine("<?xml version=\"1.0\" " + 
                         "encoding=\"utf-8\"?>");
            sw.WriteLine("<?mso-application progid" + 
                         "=\"Excel.Sheet\"?>");
            sw.WriteLine("<Workbook xmlns=\"urn:" + 
                         "schemas-microsoft-com:office:spreadsheet\">");
            sw.WriteLine("<DocumentProperties " + 
                         "xmlns=\"urn:schemas-microsoft-com:" + 
                         "office:office\">");
            sw.WriteLine("<Author>Arasu Elango</Author>");
            sw.WriteLine("<Created>" +  
                         DateTime.Now.ToLocalTime().ToLongDateString() + 
                         "</Created>");
            sw.WriteLine("<LastSaved>" + 
                         DateTime.Now.ToLocalTime().ToLongDateString() + 
                         "</LastSaved>");
            sw.WriteLine("<Company>Atom8 IT Solutions (P) " + 
                         "Ltd.,</Company>");
            sw.WriteLine("<Version>12.00</Version>");
            sw.WriteLine("</DocumentProperties>");
            sw.WriteLine("<Worksheet ss:Name=\"Silverlight Export\" " + 
               "xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\">");
            sw.WriteLine("<Table>");
        }
        sw.Write(strBuilder.ToString());
        if (strFormat == "XML")
        {
            sw.WriteLine("</Table>");
            sw.WriteLine("</Worksheet>");
            sw.WriteLine("</Workbook>");
        }
        sw.Close();
    }
}

The ExportDataGrid method prompts to the user to select the output save file name. Based on the user selection, the method determines the format to save -- XML or CSV. The Excel XML format used is not compatible with Microsoft Excel 2003 or earlier.

The row contents are built by a method named BuildStringOfRow.

private static void BuildStringOfRow(StringBuilder strBuilder, 
        List<string> lstFields, string strFormat)
{
    switch (strFormat)
    {
        case "XML":
            strBuilder.AppendLine("<Row>");
            strBuilder.AppendLine(String.Join("\r\n", lstFields.ToArray()));
            strBuilder.AppendLine("</Row>");
            break;
        case "CSV":
            strBuilder.AppendLine(String.Join(",", lstFields.ToArray()));
            break;
    }
}

The above method builds the row contents string as per the output format. Formatting of individual fields is done by a method named FormatField.

private static string FormatField(string data, string format)
{
    switch (format)
    {
        case "XML":
            return String.Format("<Cell><Data ss:Type=\"String" + 
               "\">{0}</Data></Cell>", data);
        case "CSV":
            return String.Format("\"{0}\"", 
              data.Replace("\"", "\"\"\"").Replace("\n", 
              "").Replace("\r", ""));
    }
    return data;
}

The FormatField method returns the data formatted as per the output format.

How to use

After including the attached code (DataGridExtensions.cs) to your project, you can initiate the export of the DataGrid contents by calling the Export() method of the DataGrid. For example, if the DataGrid name is objDataGrid, you will be calling objDataGrid.Export() to invoke the export.

Points of interest

This code generates the Excel file in XML format. I found exporting in XML much easier than exporting into the XLS or XLSX format.

History

  • Version 1 - December 1, 2009.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

raelango
Architect Atom8 IT Solutions (P) Ltd
India India
Member
I have been programming since 1991. I consider programming as my passion. I founded Atom8 IT Solutions (P) Ltd., in April 2009 and have been developing applications in Microsoft Technologies (mainly C#, Silverlight).
 
My specialization has been on the US healthcare domain (Medical Transcription, Patient Financial Services, EMRs).

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberYasodha.eng28 Apr '13 - 23:22 
QuestionTo hide some selected columns in the exported filemembermeetprabhum30 Oct '12 - 23:07 
GeneralIf the characters is chinese , it will appear garbled. [modified]memberstarrycheng2 Aug '12 - 20:22 
QuestionProblemmemberaa_rojasm25 Jun '12 - 6:45 
GeneralRe: Problem [modified]memberSpeedyCoder1 Jul '12 - 9:41 
QuestionExport Silverlight DataGrid to Excel XML/CSVmemberVikramdcecse8 Jun '12 - 7:58 
QuestionEmptymemberMember 875655724 Mar '12 - 0:45 
GeneralMy vote of 5memberEderM222 Feb '12 - 7:21 
QuestionHow to Export Images to excel in silver lightmemberMember 401717417 Feb '12 - 3:17 
QuestionHow to have multiple worksheetsmemberS.R.H12 Feb '12 - 22:19 
GeneralMy vote of 5memberShilpa from Mysore1 Feb '12 - 23:21 
QuestionNice work, thanks!memberMember 839692426 Dec '11 - 13:28 
QuestionChanges to work with nullable typesmemberJohhLewis21 Dec '11 - 3:37 
GeneralMy vote of 5memberT. Abdul Rahman9 Oct '11 - 21:03 
Suggestionnested propertiesmemberrafa123413 Sep '11 - 5:24 
GeneralRe: nested propertiesmemberawgtek11 Sep '12 - 10:03 
GeneralNumber cellsmemberLARS MORTEN NYGAARD8 May '11 - 21:59 
QuestionColumn Headersmemberchildg7 Feb '11 - 11:59 
AnswerRe: Column Headersmemberraelango7 Feb '11 - 15:38 
GeneralMy vote of 5membertechnette27 Jan '11 - 15:24 
GeneralMy vote of 5memberMember 47608858 Dec '10 - 20:51 
GeneralGreat sample but failsmemberdwf200824 Nov '10 - 5:53 
GeneralRe: Great sample but failsmemberraelango24 Nov '10 - 21:38 
GeneralMy vote of 5membermcaayyappan23 Sep '10 - 0:18 
GeneralPlease advise... [modified]memberAlexWang201021 Sep '10 - 11:00 
GeneralHimemberNaga Sridhar Madiraju29 Aug '10 - 21:41 
Questiondatagrid with datapagermemberPatrick Ladd10 Aug '10 - 7:52 
AnswerRe: datagrid with datapagermemberlivinho3817 Aug '10 - 23:30 
GeneralRe: datagrid with datapagermemberraelango17 Aug '10 - 23:56 
GeneralRe: datagrid with datapagermemberuscgc7248 Sep '10 - 4:43 
AnswerRe: datagrid with datapagermemberlakson25 Dec '10 - 2:05 
GeneralOutstanding! One comment to handle NULL values in data...memberNoah Wollowick21 Jul '10 - 13:41 
Questionwhich version of SL is this example?memberzondymothoa13 Jun '10 - 21:49 
AnswerRe: which version of SL is this example?memberraelango13 Jun '10 - 22:24 
GeneralReplacing escape charactersmemberseonsoo25 May '10 - 22:54 
GeneralOutstanding!memberDavid_Murdoch30 Apr '10 - 12:24 
GeneralRe: Outstanding!memberraelango30 Apr '10 - 21:03 
Generalnice work dudemembersachinblore27 Apr '10 - 7:52 
Generalno me graba la informacion en los controlesmemberccmmasi22 Apr '10 - 12:16 
GeneralRe: no me graba la informacion en los controlesmemberraelango22 Apr '10 - 20:28 
GeneralException if datacell is nullmemberfrancesconuma2 Mar '10 - 0:46 
GeneralRe: Exception if datacell is nullmemberraelango2 Mar '10 - 1:38 
QuestionCan the file be give a name in code?member2 Rocks17 Feb '10 - 8:08 
AnswerRe: Can the file be give a name in code?memberraelango17 Feb '10 - 18:28 
Generalcan't work when the datagrid is binded to a dataview.memberMember 1467027 Jan '10 - 16:46 
GeneralRe: can't work when the datagrid is binded to a dataview.memberraelango7 Jan '10 - 18:14 
GeneralRe: can't work when the datagrid is binded to a dataview.memberlivinho3828 Jul '10 - 3:21 
GeneralDataGridTemplateColumn alternative approach if this column contains a ContentControlmemberjasonp8 Dec '09 - 12:37 
GeneralRe: DataGridTemplateColumn alternative approach if this column contains a ContentControlmemberraelango8 Dec '09 - 15:39 
GeneralRe: DataGridTemplateColumn alternative approach if this column contains a ContentControlmemberjasonp9 Dec '09 - 8:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 1 Dec 2009
Article Copyright 2009 by raelango
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid