65.9K
CodeProject 正在变化。 阅读更多。
Home

将 Silverlight DataGrid 导出到 Excel XML/CSV

starIconstarIconstarIconstarIconstarIcon

5.00/5 (23投票s)

2009年12月1日

CPOL

2分钟阅读

viewsIcon

219023

downloadIcon

4980

本文档解释了如何将 DataGrid 的内容导出到 Excel/CSV。

引言

最终用户有多种原因需要将应用程序中的数据导出到 Excel 兼容格式(通常用于进一步分析/使用或数据)。本文档解释了如何在 Silverlight DataGrid 中包含数据导出功能。

背景

我正在将一些 ASP.NET 代码迁移到 Silverlight 应用程序。我感觉 Silverlight 缺少的一个功能是能够将 DataGrid 的内容导出给最终用户。为了解决这个问题,我为 DataGrid 控件创建了一个扩展。当将附件(DataGridExtensions.cs)包含在项目中时,“导出”扩展会自动提供给项目中使用的所有 DataGrid 控件。

使用代码

此模块暴露了两种方法

  • Export (this DataGrid dg) - 通过提供导出功能来扩展 DataGrid 控件。
  • ExportDataGrid (DataGrid dGrid) - 此方法由 DataGrid 导出扩展内部调用。但是,也可以直接调用此方法。
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();
    }
}

ExportDataGrid 方法会提示用户选择输出保存文件名。根据用户的选择,该方法确定保存格式 - XML 或 CSV。使用的 Excel XML 格式与 Microsoft Excel 2003 或更早版本不兼容。

行内容由一个名为 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;
    }
}

上述方法根据输出格式构建行内容字符串。单个字段的格式化由一个名为 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;
}

FormatField 方法根据输出格式返回格式化的数据。

如何使用

在将附件(DataGridExtensions.cs)包含到您的项目中后,可以通过调用 DataGridExport() 方法来启动 DataGrid 内容的导出。例如,如果 DataGrid 的名称是 objDataGrid,您将调用 objDataGrid.Export() 来调用导出。

关注点

此代码以 XML 格式生成 Excel 文件。我发现以 XML 格式导出比导出到 XLS 或 XLSX 格式更容易。

历史

  • 版本 1 - 2009 年 12 月 1 日。
© . All rights reserved.