如何在WPF中将DataGrid导出到Excel

时间:2019-05-28 22:57:13

标签: c# .net excel wpf datagrid

我正在做一个项目,但是我无法将DataGrid中的信息导出到excel。

我该怎么办?

2 个答案:

答案 0 :(得分:0)

我创建了一个简单的应用程序,用于将DataGrid导出到Excel文件。

Xaml:

<StackPanel>
    <!--Export button-->
    <Button Name="ToExcelButton"
            Content="ToExcel"
            Margin="8"
            Padding="8"
            HorizontalAlignment="Center"
            Click="ToExcelButton_OnClick"/>

    <!--Users DataGrid-->
    <DataGrid Name="UsersDataGrid"
              AutoGenerateColumns="False"
              DataContext="{Binding}">
        <DataGrid.Columns>
            <DataGridTextColumn Header="ID" Binding="{Binding Id}" Width="120" />
            <DataGridTextColumn Header="Name" Binding="{Binding Name}" Width="180" />
            <DataGridTextColumn Header="Username" Binding="{Binding Username}" Width="150" />
        </DataGrid.Columns>
    </DataGrid>
</StackPanel>

C#:

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();
        UsersDataGrid.ItemsSource = GetUsers();
    }

    private static IEnumerable<User> GetUsers()
    {
        var users = new List<User>
        {
            new User {Id = 1, Name = "User1", Username = "u123"},
            new User {Id = 2, Name = "User2", Username = "u321"},
            new User {Id = 3, Name = "User3", Username = "u852"},
        };

        return users;
    }

    private void ToExcelButton_OnClick(object sender, RoutedEventArgs e)
    {
        var d = UsersDataGrid.ItemsSource.Cast<User>();
        var data = ToDataTable(d.ToList());
        ToExcelFile(data, "test.xlsx");
    }

    public static DataTable ToDataTable<T>(List<T> items)
    {
        var dataTable = new DataTable(typeof(T).Name);

        //Get all the properties
        var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
        foreach (var prop in properties)
        {
            //Defining type of data column gives proper data table 
            var type = (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) ? Nullable.GetUnderlyingType(prop.PropertyType) : prop.PropertyType);
            //Setting column names as Property names
            dataTable.Columns.Add(prop.Name, type);
        }
        foreach (var item in items)
        {
            var values = new object[properties.Length];
            for (var i = 0; i < properties.Length; i++)
            {
                //inserting property values to data table rows
                values[i] = properties[i].GetValue(item, null);
            }
            dataTable.Rows.Add(values);
        }
        //put a breakpoint here and check data table
        return dataTable;
    }

    public static void ToExcelFile(DataTable dataTable, string filePath, bool overwriteFile = true)
    {
        if (File.Exists(filePath) && overwriteFile)
            File.Delete(filePath);

        using (var connection = new OleDbConnection())
        {
            connection.ConnectionString = $"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={filePath};" +
                                          "Extended Properties='Excel 12.0 Xml;HDR=YES;'";
            connection.Open();
            using (var command = new OleDbCommand())
            {
                command.Connection = connection;
                var columnNames = (from DataColumn dataColumn in dataTable.Columns select dataColumn.ColumnName).ToList();
                var tableName = !string.IsNullOrWhiteSpace(dataTable.TableName) ? dataTable.TableName : Guid.NewGuid().ToString();
                command.CommandText = $"CREATE TABLE [{tableName}] ({string.Join(",", columnNames.Select(c => $"[{c}] VARCHAR").ToArray())});";
                command.ExecuteNonQuery();
                foreach (DataRow row in dataTable.Rows)
                {
                    var rowValues = (from DataColumn column in dataTable.Columns select (row[column] != null && row[column] != DBNull.Value) ? row[column].ToString() : string.Empty).ToList();
                    command.CommandText = $"INSERT INTO [{tableName}]({string.Join(",", columnNames.Select(c => $"[{c}]"))}) VALUES ({string.Join(",", rowValues.Select(r => $"'{r}'").ToArray())});";
                    command.ExecuteNonQuery();
                }
            }

            connection.Close();
        }
    }
}

用户类别:

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Username { get; set; }
}

答案 1 :(得分:0)

在应用程序中安装 Microsoft.Office.Interop.Excel Nuget程序包。右键单击项目-> “参考”,然后选择“管理NuGet软件包...” ,然后仅搜索Excel。否则,选择工具-> Nuget软件包管理器->软件包管理器控制台-> ,然后安装Excel nuget(https://www.nuget.org/packages/Microsoft.Office.Interop.Excel/)。

绑定DataGrid中的项目,然后将数据导出到excel,如下所示,

        private void btnExport_Click(object sender, RoutedEventArgs e)
        {            
            Microsoft.Office.Interop.Excel.Application excel = null;
            Microsoft.Office.Interop.Excel.Workbook wb = null;
            object missing = Type.Missing;
            Microsoft.Office.Interop.Excel.Worksheet ws = null;
            Microsoft.Office.Interop.Excel.Range rng = null;

            // collection of DataGrid Items
            var dtExcelDataTable = ExcelTimeReport(txtFrmDte.Text, txtToDte.Text, strCondition);

            excel = new Microsoft.Office.Interop.Excel.Application();
            wb = excel.Workbooks.Add();
            ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.ActiveSheet;
            ws.Columns.AutoFit();
            ws.Columns.EntireColumn.ColumnWidth = 25;

            // Header row
            for (int Idx = 0; Idx < dtExcelDataTable.Columns.Count; Idx++)
            {
                ws.Range["A1"].Offset[0, Idx].Value = dtExcelDataTable.Columns[Idx].ColumnName;                    
            }

            // Data Rows
            for (int Idx = 0; Idx < dtExcelDataTable.Rows.Count; Idx++)
            {  
                ws.Range["A2"].Offset[Idx].Resize[1, dtExcelDataTable.Columns.Count].Value = dtExcelDataTable.Rows[Idx].ItemArray;
            }

            excel.Visible = true;
            wb.Activate();
        }