You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Wpf中DataGrid内容复制到DataTable后导出Excel异常求助

解决DataGrid转DataTable再导出Excel不符合预期的问题

我来帮你排查这个问题~从你给出的代码片段来看,目前的实现有几个关键漏洞,正是这些导致导出结果不符合预期:

  • 只创建了DataTable的列,但没有设置列名,导出后Excel会显示默认的Column1、Column2这类无意义名称
  • 行数据的赋值逻辑不完整(代码里dr = dt.NewRow...后面的逻辑缺失)
  • 直接遍历dataGrid.Items可能会包含非数据行(比如表头、空占位行)

下面是修正后的完整实现,包含DataGrid转DataTable的正确逻辑,以及导出到Excel的可靠方案:

第一步:正确将DataGrid数据复制到DataTable

private DataTable ConvertDataGridToDataTable(DataGrid dataGrid)
{
    DataTable dt = new DataTable();

    // 1. 创建列并设置列名(优先用绑定字段名,无绑定则用列头文本)
    foreach (DataGridColumn column in dataGrid.Columns)
    {
        string columnName = (column as DataGridBoundColumn)?.Binding.Path.Path ?? column.Header.ToString();
        // 可根据实际绑定数据类型调整typeof(object),比如typeof(string)/typeof(int)
        dt.Columns.Add(columnName, typeof(object));
    }

    // 2. 遍历DataGrid的有效数据行(跳过空占位行)
    foreach (var item in dataGrid.Items)
    {
        // 跳过DataGrid默认的空占位行(用于新增数据的行)
        if (item == CollectionView.NewItemPlaceholder)
            continue;

        DataRow dr = dt.NewRow();
        foreach (DataGridColumn column in dataGrid.Columns)
        {
            // 获取单元格的显示值(如果是自定义模板列,需根据控件类型调整)
            var cellValue = (column.GetCellContent(item) as TextBlock)?.Text;
            // 空值用DBNull填充,避免导出报错
            dr[column.Header.ToString()] = cellValue ?? DBNull.Value;
        }
        dt.Rows.Add(dr);
    }

    return dt;
}

第二步:将DataTable导出到Excel

这里用常用的EPPlus库(需先通过NuGet安装EPPlus包),操作简单且兼容性好:

private void btnSave_Click(object sender, RoutedEventArgs e)
{
    try
    {
        DataTable dt = ConvertDataGridToDataTable(dataGrid);

        // 弹出保存文件对话框
        SaveFileDialog saveFileDialog = new SaveFileDialog();
        saveFileDialog.Filter = "Excel文件 (*.xlsx)|*.xlsx";
        if (saveFileDialog.ShowDialog() == true)
        {
            using (var package = new ExcelPackage(new FileInfo(saveFileDialog.FileName)))
            {
                ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("导出数据");
                // 从A1单元格开始加载DataTable数据,true表示包含表头
                worksheet.Cells["A1"].LoadFromDataTable(dt, true);
                // 自动调整列宽,优化显示效果
                worksheet.Cells.AutoFitColumns();
                // 保存Excel文件
                package.Save();
            }
            MessageBox.Show("导出成功!");
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show($"导出失败:{ex.Message}");
    }
}

额外注意事项

  • 如果你的DataGrid使用了自定义模板列(比如包含TextBox的列),需要调整GetCellContent的逻辑,比如获取TextBox.Text而不是TextBlock.Text
  • 若不想使用EPPlus,也可以用.NET原生的OleDb方式导出,但配置步骤更繁琐,EPPlus是更推荐的轻量方案

内容的提问来源于stack exchange,提问作者Nagaraju Kuricheti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:15:28