WPF DataGrid导出Excel仅表头且Cells报错:缺少引用求助
WPF DataGrid导出Excel完整解决方案
问题根源
你代码里的dgEndOfYear.Items[i].Cells报错,核心原因是WPF DataGrid与WinForms DataGridView架构不同:WPF DataGrid的Items集合存储的是绑定的业务数据对象(如你的年度统计实体),而非带Cells属性的行对象,自然无法访问Cells。
修复步骤及完整代码
1. 获取真实数据源
你的DataGrid绑定到CollectionViewSource,需先获取其包装的原始数据集合:
// 获取CollectionViewSource绑定的原始数据集 var collectionView = (CollectionViewSource)FindResource("ItemCollectionViewSources"); var dataItems = collectionView.Source as IEnumerable<dynamic>; // 若已知实体类型,替换为强类型如IEnumerable<YearlyStat>
2. 修改导出逻辑(完整按钮事件代码)
private void btnExcel_Click(object sender, RoutedEventArgs e) // WPF按钮事件参数为RoutedEventArgs,而非EventArgs { Microsoft.Office.Interop.Excel._Application app = new Microsoft.Office.Interop.Excel.Application(); Microsoft.Office.Interop.Excel._Workbook workbook = app.Workbooks.Add(Type.Missing); Microsoft.Office.Interop.Excel._Worksheet worksheet = null; app.Visible = true; worksheet = workbook.Sheets["Sheet1"]; worksheet = workbook.ActiveSheet; worksheet.Name = "年度统计导出"; // 导出表头 for (int i = 1; i <= dgEndOfYear.Columns.Count; i++) { worksheet.Cells[1, i] = dgEndOfYear.Columns[i - 1].Header; } // 获取数据源,为空则直接返回 var collectionView = (CollectionViewSource)FindResource("ItemCollectionViewSources"); var dataItems = collectionView.Source as IEnumerable<dynamic>; if (dataItems == null) return; // 导出数据行 int rowIndex = 2; foreach (var item in dataItems) { worksheet.Cells[rowIndex, 1] = item.CalendarYear; worksheet.Cells[rowIndex, 2] = item.MonthName; worksheet.Cells[rowIndex, 3] = item.SumGal; worksheet.Cells[rowIndex, 3].NumberFormat = "#,##0"; // 保持千分位格式 rowIndex++; } // 修复路径转义问题,用@符号避免转义字符解析错误 workbook.SaveAs(@"C:\output.xls", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing); // 释放COM对象,防止Excel进程后台残留 System.Runtime.InteropServices.Marshal.ReleaseComObject(worksheet); System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook); app.Quit(); System.Runtime.InteropServices.Marshal.ReleaseComObject(app); }
3. 关键修复点解析
- 事件参数修正:WPF按钮点击事件参数为
RoutedEventArgs,替换原代码的EventArgs以解决编译错误。 - 移除Cells访问:直接通过数据对象的属性(
CalendarYear/MonthName/SumGal)取值,符合WPF数据绑定的设计逻辑。 - 循环逻辑修正:原代码遍历列数是错误的,改为遍历数据源的每一行数据。
- 路径转义修复:
"c:\output.xls"会被解析为转义字符,改为@"c:\output.xls"或"c:\\output.xls"。 - COM对象释放:显式释放Excel相关COM对象,避免程序关闭后Excel进程仍在后台运行。
4. 强类型优化建议
若已知数据实体类名(如YearlyStat),将IEnumerable<dynamic>替换为IEnumerable<YearlyStat>,可获得编译时类型检查,避免运行时错误:
var dataItems = collectionView.Source as IEnumerable<YearlyStat>;
内容的提问来源于stack exchange,提问作者Mr.E
相关产品推荐
相关产品推荐

