Silverlight DataGrid:导出到excel或csv

有没有办法可以将我的Silverlight DataGrid数据导出到excel或csv?

我在网上搜索但找不到任何例子!

非常感谢

Silverlight 3更改了此问题的答案,因为它使用户能够在用户桌面上指定的位置创建文件。 我修改了DaniCE提交的代码,将一些内容分成了一些可读性方法,并使用了Excel应该识别的松散定义的CSV格式。

private void exportHistoryButton_Click(object sender, RoutedEventArgs e) { string data = ExportDataGrid(true, historyDataGrid); SaveFileDialog sfd = new SaveFileDialog() { DefaultExt = "csv", Filter = "CSV Files (*.csv)|*.csv|All files (*.*)|*.*", FilterIndex = 1 }; if (sfd.ShowDialog() == true) { using (Stream stream = sfd.OpenFile()) { using (StreamWriter writer = new StreamWriter(stream)) { writer.Write(data); writer.Close(); } stream.Close(); } } } private string FormatCSVField(string data) { return String.Format("\"{0}\"", data.Replace("\"", "\"\"\"") .Replace("\n", "") .Replace("\r", "") ); } public 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 headers = new List(); 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 csvRow = new List(); 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(); } 

我用剪贴板找到了这个 。

要使代码通用,您可以修改第一个示例以读取列绑定并使用reflection将它们应用于数据:

 public String ExportDataGrid(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.DataContext as System.Collections.IList); if (source == null) return ""; foreach (Object data in source) { foreach (DataGridColumn col in datagrid.Columns) { if (col is DataGridBoundColumn) { binding = (col as DataGridBoundColumn).Binding; colPath = binding.Path.Path; propInfo = data.GetType().GetProperty(colPath); if (propInfo != null) { strBuilder.Append(propInfo.GetValue(data, null).ToString()); strBuilder.Append(","); } } } strBuilder.Append("\r\n"); } return strBuilder.ToString(); } 

当然,它仅在绑定路径是属性名称时才有效。 对于更高级的路径,您必须将绑定应用于数据(我想这将是一个更好的解决方案,但我现在不确定如何执行此操作)。

我不认为Silverlight提供了下载文件的方法。 您可以在应用中添加一个调用URL的按钮,即http://www.mysite.com/generateexcelfile.aspx 。 包含Querystring值用于生成Silverlight应用程序中显示的数据的参数,运行查询并使用您喜欢的Excel文件生成组件即时生成文件。 重定向到它,它将下载到用户的系统。

我知道这是一个老post,但它确实帮助了我。 我做了一些编辑,使它适用于silverlight 4,转换和excel。 我想要快速导出,所以我首先使用CSV然后用excel打开它。 此代码适用于silverlight web和oob提升信任。 在Web中不会打开excel。

  private static void OpenExcelFile(string Path) { dynamic excelApp; excelApp = AutomationFactory.CreateObject("Excel.Application"); dynamic workbook = excelApp.workbooks; object oMissing = Missing.Value; workbook = excelApp.Workbooks.Open(Path, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing); dynamic sheet = excelApp.ActiveSheet; // open the existing sheet sheet.Cells.EntireColumn.AutoFit(); excelApp.Visible = true; } private static string FormatCSVField(string data) { return String.Format("\"{0}\"", data.Replace("\"", "\"\"\"") .Replace("\n", "") .Replace("\r", "") ); } public static string ExportDataGrid(DataGrid grid,string SaveFileName,bool AutoOpen) { string colPath; System.Reflection.PropertyInfo propInfo; System.Windows.Data.Binding binding; System.Text.StringBuilder strBuilder = new System.Text.StringBuilder(); var source = grid.ItemsSource; if (source == null) return ""; List headers = new List(); 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 (var data in source) { List csvRow = new List(); 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) { string valueConverted = ""; if (binding.Converter.GetType().ToString() != "System.Windows.Controls.DataGridValueConverter") valueConverted = binding.Converter.Convert(propInfo.GetValue(data, null), typeof(System.String), binding.ConverterParameter, System.Globalization.CultureInfo.CurrentCulture).ToString(); else valueConverted = FormatCSVField(propInfo.GetValue(data, null) == null ? "" : propInfo.GetValue(data, null).ToString()); csvRow.Add(valueConverted.ToString()); } } } strBuilder .Append(String.Join(",", csvRow.ToArray())) .Append("\r\n"); } if (AutomationFactory.IsAvailable) { var sampleFile = "\\" + SaveFileName; var path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); path += "\\Pement"; if (!System.IO.Directory.Exists(path)) { System.IO.Directory.CreateDirectory(path); } else { var files = System.IO.Directory.EnumerateFiles(path); foreach (var item in files) { try { System.IO.File.Delete(item); } catch { } } } StreamWriter sw = File.CreateText(path + sampleFile); sw.WriteLine(strBuilder.ToString()); sw.Close(); if (AutoOpen) OpenExcelFile(path + sampleFile, true, true); } else { SaveFileDialog sfd = new SaveFileDialog() { DefaultExt = "csv", Filter = "CSV Files (*.csv)|*.csv|All files (*.*)|*.*", FilterIndex = 1 }; if (sfd.ShowDialog() == true) { using (Stream stream = sfd.OpenFile()) { using (StreamWriter writer = new StreamWriter(stream)) { writer.Write(strBuilder.ToString()); writer.Close(); } stream.Close(); } } } return strBuilder.ToString(); } 

我会说你可以使用ControlTemplate添加导出按钮,然后迭代DataSource每个项目,然后使用Columns每一列使用GetCellContent方法获取每个单元格的内容,或者使用DataGridColumn的绑定信息以获取适当的单元格值。 然后,您可以获取此内容的显示值并将其写入报告。

就像是…

 foreach (YourType item in grid.DataSource) { foreach (DataGridColumn column in grid.Columns) { FrameworkElement cellContent = column.GetCellContent(item); // Now, determine the type of cell content and act accordingly. TextBlock block = cellContent as TextBlock; if (block != null) { // Report text value... } // ...etc... } } 

或者使用DaniCE描述的绑定信息。

检查Ryan的解决方案。 看起来不错,但不能担保,因为我刚刚发现它。 Ryan做了上面要求的DLL。

http://www.rshelby.com/post/exporting-data-from-silverilght-datagrid-to-excel.aspx

David在Dakota上面的解决方案看起来更容易实现,并且总是重定向到经典的asp.net页面,其上有数据网格,内容类型设置为excel,但是你有更多的代码需要支持可能不适用于离线的浏览器解决方案(实际上不起作用)。

无论如何,这是一项常见的任务。 我希望这里或微软的一些人想出一个Mort即插即用解决方案:)

我找到了一个从Silverlight数据网格导出CVS的扩展方法 –

http://www.codeproject.com/KB/silverlight/SilverlightDataGridExport.aspx

它有可能即插即用,但我不得不稍微调整它以使其与带有项目数据源的datagrids一起工作(参见post中的评论)。 比我更聪明,更有经验的人应该能够调整到完美。 看看它,它应该让你接近你需要的。

这些解决方案对我不起作用,所以我将它们修改为有效的解决方案。 (我的解决方案不需要字段周围的引号,所以我省略了FormatCSVField函数)

  public void SaveAs(string csvPath) { string data = ExportDataGrid(true, _flexGrid); StreamWriter sw = new StreamWriter(csvPath, false, Encoding.UTF8); sw.Write(data); sw.Close(); } public string ExportDataGrid(bool withHeaders, Microsoft.Windows.Controls.DataGrid grid) { System.Text.StringBuilder strBuilder = new System.Text.StringBuilder(); System.Collections.IEnumerable source = (grid.ItemsSource as System.Collections.IEnumerable); if (source == null) return ""; List headers = new List(); grid.Columns.ToList().ForEach(col => { if (col is Microsoft.Windows.Controls.DataGridBoundColumn) { headers.Add(col.Header.ToString()); } }); strBuilder.Append(String.Join(",", headers.ToArray())).Append("\r\n"); foreach (Object data in source) { System.Data.DataRowView d = (System.Data.DataRowView)data; strBuilder.Append(String.Join(",", d.Row.ItemArray)).Append("\r\n"); } return strBuilder.ToString(); } 

这是一个很适合我的方法http://forums.silverlight.net/forums/p/179321/404357.aspx

我需要做同样的事情。 我使用了t3rse的实现,但不得不进行一些更改。 我没有足够的声誉对他的回答发表评论,所以我会在这里列出:

  • 对于说propInfo.GetValue(data,null).ToString()的行,我在调用ToString()之前检查了GetValue返回的值是否为Null。

  • 在FormatCSVField()方法中,它用三个双引号替换了双引号。 它应该只用两个双引号替换它。

  • 该实现仅使用DataGridBoundColumn类型的列并忽略其他列。 我的列不是我希望包含的DataGridBoundColumn,因此我获得了col.SortMemberPath这些列的数据源的属性名称。