将 Silverlight DataGrid 导出到 Excel XML/CSV
本文档解释了如何将 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)包含到您的项目中后,可以通过调用 DataGrid
的 Export()
方法来启动 DataGrid
内容的导出。例如,如果 DataGrid
的名称是 objDataGrid
,您将调用 objDataGrid.Export()
来调用导出。
关注点
此代码以 XML 格式生成 Excel 文件。我发现以 XML 格式导出比导出到 XLS 或 XLSX 格式更容易。
历史
- 版本 1 - 2009 年 12 月 1 日。