【发布时间】:2019-05-28 22:57:13
【问题描述】:
我正在处理一个项目,但我无法将 DataGrid 中的信息导出到 Excel。
我该怎么做?
【问题讨论】:
-
您的问题需要更多信息。我们不知道您尝试了什么或您如何需要帮助。请查看以下链接,了解如何提出好的问题。 stackoverflow.com/help/how-to-ask
标签: c# .net excel wpf datagrid
我正在处理一个项目,但我无法将 DataGrid 中的信息导出到 Excel。
我该怎么做?
【问题讨论】:
标签: c# .net excel wpf datagrid
在您的应用程序中安装 Microsoft.Office.Interop.Excel Nuget 包。右键单击您的项目 -> “参考”并选择“管理 NuGet 包...”,然后只需搜索 Excel。否则,选择 Tools -> Nuget Package Manager -> Package Manager Console -> 然后安装 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();
}
【讨论】:
我创建了一个简单的应用程序来将 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; }
}
【讨论】: