Introduction
Here in this blog, we will see how to export datagrid to excel C# WPF and WPF datagrid export to CSV without using any library or third party library.
Getting Started
Lets say you have a WPF datagrid where you are populating list of data like below image in your project for reporting or any other purpose. You want export the populated data from WPF datagrid to excel or csv file with help of a button.
WPF DataGrid Export to Excel |
We will see how to export populated data from WPF Datagrid to CSV files using the clipboard rather than using any library. On the button click event we will copy WPF Datagrid data into clipboard then will export it to CSV file. The following code helps copy the WPF Datagrid data into the clipboard.
this.dgvStudents.SelectAllCells();
this.dgvStudents.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
ApplicationCommands.Copy.Execute(null, this.dgvStudents);
this.dgvStudents.UnselectAllCells();
The below code snippet helps to retrieve data from clipboard then same it into csv file.
String result = (string) Clipboard.GetData(DataFormats.CommaSeparatedValue);
try
{
StreamWriter sw = new StreamWriter("wpfdata.csv");
sw.WriteLine(result);
sw.Close();
Process.Start("wpfdata.csv");
}
catch(Exception ex)
{}
Above are the two code examples which actually export the populated data in WPF Datagrid into CSV file. Now will demonstrate how to achieve WPF Datagrid to excel in WPF project.
Demonstration
Open your WPF project where you want to export data from WPF Datagrid to excel, go that container control(WPF Windows or WPF User control) where you have used Datagrid which data you want to export.
I hope that you have already taken a button in your project for the purpose of data exportation or if you have taken any other control , in the event put the below code. For example, if you want to export data in the button click event then put the below code in the button event.
private void Button_Click_1(object sender, RoutedEventArgs e)
{
this.dgvStudents.SelectAllCells();
this.dgvStudents.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
ApplicationCommands.Copy.Execute(null, this.dgvStudents);
this.dgvStudents.UnselectAllCells();
String result = (string) Clipboard.GetData(DataFormats.CommaSeparatedValue);
try
{
StreamWriter sw = new StreamWriter("wpfdata.csv");
sw.WriteLine(result);
sw.Close();
Process.Start("wpfdata.csv");
}
catch(Exception ex)
{}
}
The above code example in the button click event, contains all the code that copies WPF datagrid populated data into clipboard by selecting all the cells of WPF datagrid then with help of StreamWriter class exports to csv file(«wpfdata.csv»). After saving data into file, it opens the csv file in Excel application.
Go and see the below full code, if you have doubts. The full code is given by separating classes for better understanding, you can use this classes to build demo project.
Main Window XAML
<Window x:Class="WPFDataGridExport.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525">
<DockPanel>
<StackPanel Orientation="Horizontal" FlowDirection="RightToLeft" DockPanel.Dock="Bottom">
<Button Content="Export" Click="Button_Click_1" Margin="5"></Button>
</StackPanel>
<DataGrid AutoGenerateColumns="False" Name="dgvStudents">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Width="*" Binding="{Binding Path=Name, Mode=Default}"></DataGridTextColumn>
<DataGridTextColumn Header="Roll no." Width="100" Binding="{Binding Path=RollNo, Mode=Default}"></DataGridTextColumn>
<DataGridTextColumn Header="Age" Width="100" Binding="{Binding Path=Age, Mode=Default}"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</DockPanel>
</Window>
Student Class
public class Student
{
public string Name { get; set; }
public int RollNo { get; set; }
public int Age { get; set; }
}
Main Window CS
namespace wpfexporttoexcel
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public List<Student> Students
{
get;
set;
}
public MainWindow()
{
InitializeComponent();
FillDate();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
this.dgvStudents.SelectAllCells();
this.dgvStudents.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
ApplicationCommands.Copy.Execute(null, this.dgvStudents);
this.dgvStudents.UnselectAllCells();
String result = (string)Clipboard.GetData(DataFormats.CommaSeparatedValue);
try
{
StreamWriter sw = new StreamWriter("export.csv");
sw.WriteLine(result);
sw.Close();
Process.Start("export.csv");
}
catch (Exception ex)
{ }
}
private void FillDate()
{
this.Students = new List<Student>();
this.Students.Add(new Student()
{
Name = "Kailash",
RollNo = 1,
Age = 10
});
this.Students.Add(new Student()
{
Name = "Munna",
RollNo = 2,
Age = 10
});
this.Students.Add(new Student()
{
Name = "Suraj",
RollNo = 3,
Age = 10
});
this.Students.Add(new Student()
{
Name = "Kiran",
RollNo = 4,
Age = 10
});
this.Students.Add(new Student()
{
Name = "Akash",
RollNo = 5,
Age = 10
});
this.Students.Add(new Student()
{
Name = "Vishal",
RollNo = 6,
Age = 10
});
this.Students.Add(new Student()
{
Name = "Manoj",
RollNo = 7,
Age = 10
});
this.Students.Add(new Student()
{
Name = "Ajay",
RollNo = 8,
Age = 10
});
this.Students.Add(new Student()
{
Name = "Rushi",
RollNo = 9,
Age = 10
});
this.Students.Add(new Student()
{
Name = "Ruchit",
RollNo = 10,
Age = 10
});
this.dgvStudents.ItemsSource = this.Students;
}
}
}
Summary
In the above example we saw how to export data from WPF DataGrid to CSV file, I hope you have enjoyed it a lot.
Thanks
- Download source — 715.19 KB
Introduction
Often developers get requirements from business users to make the data in any collection items (listview
, gridview
, listbox
) exportable, helping them to use it according to their need — when the application is not running. For this purpose, developers normally export the data to PDF, Word, Excel and RTF formats. DataGrid
control was introduced in WPFToolkit which can be used along with VS 2008. Currently, Visual Studio 2010 has it with in the bundle itself. In this article, we will explore how to create an Excel file from a datagrid
. We will try to explain the concept in a very simple manner. According to the need, developers can change them.
Exporting the WPF DataGrid to Microsoft Excel
Step #1
Open a Visual Studio 2008 instance. Ensure WPF Toolkit is installed on your machine. If not, kindly download form this link. Add the reference of WPFToolkit without fail.
Step #2
Create a WPF screen as shown in the code snippet XAML File:
<Window x:Class="ExportToExcel.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:toolkit="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit" xmlns:local="clr-namespace:ExportToExcel" Title="DataGrid Excel Export" Height="400" Width="250"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="30"/> <RowDefinition Height="150"/> <RowDefinition Height="30"/> <RowDefinition Height="150"/> </Grid.RowDefinitions> <Button Grid.Row="0" HorizontalAlignment="Right" Width="50" Height="25" Content="Export" Click="btnEmployee_Click" Name="btnEmployee"/> <toolkit:DataGrid Grid.Row="1" Name="dgEmployee" SelectionMode="Single" AutoGenerateColumns="False" IsReadOnly="True" Margin="5,5,5,5"> <toolkit:DataGrid.Columns> <toolkit:DataGridTextColumn Binding="{Binding Path=Id}" Header="Id" Width="45"/> <toolkit:DataGridTextColumn Binding="{Binding Path=Name}" Header="Name" Width="100"/> <toolkit:DataGridTextColumn Binding="{Binding Path=Designation}" Header="Designation" Width="*"/> </toolkit:DataGrid.Columns> </toolkit:DataGrid> <Button Grid.Row="2" HorizontalAlignment="Right" Width="50" Height="25" Content="Export" Click="btnBook_Click" Name="btnBook"/> <toolkit:DataGrid Grid.Row="3" Name="dgBook" SelectionMode="Single" AutoGenerateColumns="False" IsReadOnly="True" Margin="5,5,5,5"> <toolkit:DataGrid.Columns> <toolkit:DataGridTextColumn Binding="{Binding Path=ISBN}" Header="ISBN" Width="45"/> <toolkit:DataGridTextColumn Binding="{Binding Path=Title}" Header="Title" Width="100"/> <toolkit:DataGridTextColumn Binding="{Binding Path=Author}" Header="Author" Width="*"/> </toolkit:DataGrid.Columns> </toolkit:DataGrid> </Grid> </Window>
Step #3
The screen will look like this:
Step #4
We are going to bind two different classes to two datagrid
s. The first datagrid
is bound with class Employees
and second one with Books
:
public class Employees : List<employee> { } public class Employee { private int id; public int Id { get { return id; } set { id = value; } } private string name; public string Name { get { return name; } set { name = value; } } private string designation; public string Designation { get { return designation; } set { designation = value; } } } public class Books : List<book> { } public class Book { private int iSBN; public int ISBN { get { return iSBN; } set { iSBN = value; } } private string title; public string Title { get { return title; } set { title = value; } } private string author; public string Author { get { return author; } set { author = value; } } }
Step #5
Add a little data to the classes and bind them to the datagrid
.
public Window1() { InitializeComponent(); Employees emps = new Employees(); Employee e1 = new Employee(); e1.Id = 52590; e1.Name = "Sathish"; e1.Designation = "Developer"; emps.Add(e1); Employee e2 = new Employee(); e2.Id = 52592; e2.Name = "Karthick"; e2.Designation = "Developer"; emps.Add(e2); Employee e3 = new Employee(); e3.Id = 52593; e3.Name = "Raja"; e3.Designation = "Manager"; emps.Add(e3); Employee e4 = new Employee(); e4.Id = 12778; e4.Name = "Sumesh"; e4.Designation = "Project Lead"; emps.Add(e4); Employee e5 = new Employee(); e5.Id = 12590; e5.Name = "Srini"; e5.Designation = "Project Lead"; emps.Add(e5); dgEmployee.ItemsSource = emps; Books books = new Books(); Book b1 = new Book(); b1.ISBN = 582912; b1.Title = "C#"; b1.Author = "James"; books.Add(b1); Book b2 = new Book(); b2.ISBN = 174290; b2.Title = "WPF"; b2.Author = "Smith"; books.Add(b2); Book b3 = new Book(); b3.ISBN = 095177; b3.Title = ".NET"; b3.Author = "Robert"; books.Add(b3); Book b4 = new Book(); b4.ISBN = 112275; b4.Title = "Java"; b4.Author = "Steve"; books.Add(b4); Book b5 = new Book(); b5.ISBN = 998721; b5.Title = "COBOL"; b5.Author = "John"; books.Add(b5); dgBook.ItemsSource = books; }
Step #6
The operation of exporting to Excel can be understood from the below flow diagram:
Step #7
Now we will explore the code.
public class ExportToExcel<T, U> where T : class where U : List<T> { public List<T> dataToPrint; private Excel.Application _excelApp = null; private Excel.Workbooks _books = null; private Excel._Workbook _book = null; private Excel.Sheets _sheets = null; private Excel._Worksheet _sheet = null; private Excel.Range _range = null; private Excel.Font _font = null; private object _optionalValue = Missing.Value; public void GenerateReport() { try { if (dataToPrint != null) { if (dataToPrint.Count != 0) { Mouse.SetCursor(Cursors.Wait); CreateExcelRef(); FillSheet(); OpenReport(); Mouse.SetCursor(Cursors.Arrow); } } } catch (Exception e) { MessageBox.Show("Error while generating Excel report"); } finally { ReleaseObject(_sheet); ReleaseObject(_sheets); ReleaseObject(_book); ReleaseObject(_books); ReleaseObject(_excelApp); } } private void OpenReport() { _excelApp.Visible = true; } private void FillSheet() { object[] header = CreateHeader(); WriteData(header); } private void WriteData(object[] header) { object[,] objData = new object[dataToPrint.Count, header.Length]; for (int j = 0; j < dataToPrint.Count; j++) { var item = dataToPrint[j]; for (int i = 0; i < header.Length; i++) { var y = typeof(T).InvokeMember (header[i].ToString(), BindingFlags.GetProperty, null, item, null); objData[j, i] = (y == null) ? "" : y.ToString(); } } AddExcelRows("A2", dataToPrint.Count, header.Length, objData); AutoFitColumns("A1", dataToPrint.Count + 1, header.Length); } private void AutoFitColumns(string startRange, int rowCount, int colCount) { _range = _sheet.get_Range(startRange, _optionalValue); _range = _range.get_Resize(rowCount, colCount); _range.Columns.AutoFit(); } private object[] CreateHeader() { PropertyInfo[] headerInfo = typeof(T).GetProperties(); List<object> objHeaders = new List<object>(); for (int n = 0; n < headerInfo.Length; n++) { objHeaders.Add(headerInfo[n].Name); } var headerToAdd = objHeaders.ToArray(); AddExcelRows("A1", 1, headerToAdd.Length, headerToAdd); SetHeaderStyle(); return headerToAdd; } private void SetHeaderStyle() { _font = _range.Font; _font.Bold = true; } private void AddExcelRows (string startRange, int rowCount, int colCount, object values) { _range = _sheet.get_Range(startRange, _optionalValue); _range = _range.get_Resize(rowCount, colCount); _range.set_Value(_optionalValue, values); } private void CreateExcelRef() { _excelApp = new Excel.Application(); _books = (Excel.Workbooks)_excelApp.Workbooks; _book = (Excel._Workbook)(_books.Add(_optionalValue)); _sheets = (Excel.Sheets)_book.Worksheets; _sheet = (Excel._Worksheet)(_sheets.get_Item(1)); } private void ReleaseObject(object obj) { try { System.Runtime.InteropServices.Marshal.ReleaseComObject(obj); obj = null; } catch (Exception ex) { obj = null; MessageBox.Show(ex.Message.ToString()); } finally { GC.Collect(); } } }
The class ExportToExcel
is enforced to get two parameters, T
and U
. T
parameter should be class and U
should be List of T
objects. This is to ensure that the class gets proper inputs. Also, to a datagrid
we usually bind a List of objects. The GenerateReport
method will create/initialize the Excel application, populate Excel columns and rows.
Most of the code is self explanatory, with two methods CreateHeader
and WriteData
methods having more emphasis. The CreateHeader
uses reflection to get the properties of the class that we have passed. From this data, we will print the column header in the Excel sheet. The WriteData
method knows how many columns are there (from CreateHeader
method) and total data (from dataToPrint.Count
). A two-dimensional array is formed and it is populated using reflection. The resulting two-dimensional array is populated in the Excel sheet.
Step #8
When we run the code, the WPF form will be shown to the user.
When we press the ‘Export’ button of books
and Employee datagrid
with coding as below:
private void btnBook_Click(object sender, RoutedEventArgs e) { ExportToExcel<Book, Books> s = new ExportToExcel<Book, Books>(); ICollectionView view = CollectionViewSource.GetDefaultView(dgBook.ItemsSource); s.dataToPrint = (Books)view.SourceCollection; s.GenerateReport(); } private void btnEmployee_Click(object sender, RoutedEventArgs e) { ExportToExcel<Employee, Employees> s = new ExportToExcel<Employee, Employees>(); s.dataToPrint = (Employees)dgEmployee.ItemsSource; s.GenerateReport(); }
We will get an Excel file with data as shown for Book
:
and for Employee
button as below:
The complete listing of code is as below:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using Excel = Microsoft.Office.Interop.Excel; using System.Reflection; using tool = Microsoft.Windows.Controls; using System.ComponentModel; namespace ExportToExcel { public partial class Window1 : Window { public Window1() { InitializeComponent(); Employees emps = new Employees(); Employee e1 = new Employee(); e1.Id = 52590; e1.Name = "Sathish"; e1.Designation = "Developer"; emps.Add(e1); Employee e2 = new Employee(); e2.Id = 52592; e2.Name = "Karthick"; e2.Designation = "Developer"; emps.Add(e2); Employee e3 = new Employee(); e3.Id = 52593; e3.Name = "Raja"; e3.Designation = "Manager"; emps.Add(e3); Employee e4 = new Employee(); e4.Id = 12778; e4.Name = "Sumesh"; e4.Designation = "Project Lead"; emps.Add(e4); Employee e5 = new Employee(); e5.Id = 12590; e5.Name = "Srini"; e5.Designation = "Project Lead"; emps.Add(e5); dgEmployee.ItemsSource = emps; Books books = new Books(); Book b1 = new Book(); b1.ISBN = 582912; b1.Title = "C#"; b1.Author = "James"; books.Add(b1); Book b2 = new Book(); b2.ISBN = 174290; b2.Title = "WPF"; b2.Author = "Smith"; books.Add(b2); Book b3 = new Book(); b3.ISBN = 095177; b3.Title = ".NET"; b3.Author = "Robert"; books.Add(b3); Book b4 = new Book(); b4.ISBN = 112275; b4.Title = "Java"; b4.Author = "Steve"; books.Add(b4); Book b5 = new Book(); b5.ISBN = 998721; b5.Title = "COBOL"; b5.Author = "John"; books.Add(b5); dgBook.ItemsSource = books; } private void btnBook_Click(object sender, RoutedEventArgs e) { ExportToExcel<Book, Books> s = new ExportToExcel<Book, Books>(); ICollectionView view = CollectionViewSource.GetDefaultView(dgBook.ItemsSource); s.dataToPrint = (Books)view.SourceCollection; s.GenerateReport(); } private void btnEmployee_Click(object sender, RoutedEventArgs e) { ExportToExcel<Employee, Employees> s = new ExportToExcel<Employee, Employees>(); s.dataToPrint = (Employees)dgEmployee.ItemsSource; s.GenerateReport(); } } public class ExportToExcel<T, U> where T : class where U : List<T> { public List<T> dataToPrint; private Excel.Application _excelApp = null; private Excel.Workbooks _books = null; private Excel._Workbook _book = null; private Excel.Sheets _sheets = null; private Excel._Worksheet _sheet = null; private Excel.Range _range = null; private Excel.Font _font = null; private object _optionalValue = Missing.Value; public void GenerateReport() { try { if (dataToPrint != null) { if (dataToPrint.Count != 0) { Mouse.SetCursor(Cursors.Wait); CreateExcelRef(); FillSheet(); OpenReport(); Mouse.SetCursor(Cursors.Arrow); } } } catch (Exception e) { MessageBox.Show("Error while generating Excel report"); } finally { ReleaseObject(_sheet); ReleaseObject(_sheets); ReleaseObject(_book); ReleaseObject(_books); ReleaseObject(_excelApp); } } private void OpenReport() { _excelApp.Visible = true; } private void FillSheet() { object[] header = CreateHeader(); WriteData(header); } private void WriteData(object[] header) { object[,] objData = new object[dataToPrint.Count, header.Length]; for (int j = 0; j < dataToPrint.Count; j++) { var item = dataToPrint[j]; for (int i = 0; i < header.Length; i++) { var y = typeof(T).InvokeMember(header[i].ToString(), BindingFlags.GetProperty, null, item, null); objData[j, i] = (y == null) ? "" : y.ToString(); } } AddExcelRows("A2", dataToPrint.Count, header.Length, objData); AutoFitColumns("A1", dataToPrint.Count + 1, header.Length); } private void AutoFitColumns(string startRange, int rowCount, int colCount) { _range = _sheet.get_Range(startRange, _optionalValue); _range = _range.get_Resize(rowCount, colCount); _range.Columns.AutoFit(); } private object[] CreateHeader() { PropertyInfo[] headerInfo = typeof(T).GetProperties(); List<object> objHeaders = new List<object>(); for (int n = 0; n < headerInfo.Length; n++) { objHeaders.Add(headerInfo[n].Name); } var headerToAdd = objHeaders.ToArray(); AddExcelRows("A1", 1, headerToAdd.Length, headerToAdd); SetHeaderStyle(); return headerToAdd; } private void SetHeaderStyle() { _font = _range.Font; _font.Bold = true; } private void AddExcelRows(string startRange, int rowCount, int colCount, object values) { _range = _sheet.get_Range(startRange, _optionalValue); _range = _range.get_Resize(rowCount, colCount); _range.set_Value(_optionalValue, values); } private void CreateExcelRef() { _excelApp = new Excel.Application(); _books = (Excel.Workbooks)_excelApp.Workbooks; _book = (Excel._Workbook)(_books.Add(_optionalValue)); _sheets = (Excel.Sheets)_book.Worksheets; _sheet = (Excel._Worksheet)(_sheets.get_Item(1)); } private void ReleaseObject(object obj) { try { System.Runtime.InteropServices.Marshal.ReleaseComObject(obj); obj = null; } catch (Exception ex) { obj = null; MessageBox.Show(ex.Message.ToString()); } finally { GC.Collect(); } } } public class Employees : List<Employee> { } public class Employee { private int id; public int Id { get { return id; } set { id = value; } } private string name; public string Name { get { return name; } set { name = value; } } private string designation; public string Designation { get { return designation; } set { designation = value; } } } public class Books : List<Book> { } public class Book { private int iSBN; public int ISBN { get { return iSBN; } set { iSBN = value; } } private string title; public string Title { get { return title; } set { title = value; } } private string author; public string Author { get { return author; } set { author = value; } } } }
Further Improvements
We are currently exploring the below possibilities:
- If you move the column order, the Excel sheet data produced will be the same as the data in the
List
. We want to print as seen in theDataGrid
. - If you sort the column, the Excel sheet data produced will be same as the data in the
List
. We want to print as seen in theDataGrid
. - We are exploring dynamic
Datagrid
to be exported (means user can add any number of rows, and it should be possible for them to export).
Working in a software development company specializing financial products as Senior Developer. Interested in WPF, WCF, C# and C.
I was also looking for something simillar to help export the data in the datagrid into excel, but found nothing which works.
Atlast I just converted the content of the DataGrid into a 2D array of string and exported it using the interop dll.
The code looks something like this:
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
Excel.Range rangeToHoldHyperlink;
Excel.Range CellInstance;
xlApp = new Excel.Application();
xlWorkBook = xlApp.Workbooks.Add(misValue);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
xlApp.DisplayAlerts = false;
//Dummy initialisation to prevent errors.
rangeToHoldHyperlink = xlWorkSheet.get_Range("A1", Type.Missing);
CellInstance = xlWorkSheet.get_Range("A1", Type.Missing);
for (int i = 0; i < NumberOfCols; i++)
{
for (int j = 0; j <= NumberOfRows; j++)
{
xlWorkSheet.Cells[j + 1, i + 1] = DataToWrite[j][i];
}
}
If you are looking for some formating, they are also supported in this. I wanted to add a hyperlink and the following code does that:
CellInstance = xlWorkSheet.Cells[j + 1, i + 1];
xlWorkSheet.Hyperlinks.Add(
CellInstance,
DataToWrite[j][i],
Type.Missing,
"Hover Text Comes Here",
"Text to be displayed");
If you want the first row to be the header, you can highlight them as follows:
Excel.Range Range1 = xlWorkSheet.get_Range("A1");
Range1.EntireRow.Font.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Black);
Range1.EntireRow.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightSkyBlue);
Range1.EntireRow.Font.Size = 14;
Range1.EntireRow.AutoFit();
Finally to Save the excel in a desired path:
xlWorkBook.SaveAs(@FilePath, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlWorkBook.Close();
The reference to the interop is added as follows:
Right Click on the Project name -> Click "Add reference" -> Goto "COM" tab -> Search for "Microsoft Excel Object Library" click "OK" to add the reference.
You must be using the following namespace :
using Excel = Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;
How to export the WPF DataGrid (SfDataGrid) to excel with RowHeader?
About the sample
This example illustrates how to export the WPF DataGrid (SfDataGrid) to excel with RowHeader?
WPF DataGrid (SfDataGrid) does not provide the support to export the row header. You can export the row header column by using Worksheet.InsertColumn method to insert column manually in ExcelSheet and make customization in inserted column.
private void btnExportToExcel_Click(object sender, RoutedEventArgs e) { var options = new ExcelExportingOptions(); options.ExcelVersion = ExcelVersion.Excel2013; var excelEngine = sfDataGrid.ExportToExcel(sfDataGrid.View, options); var workBook = excelEngine.Excel.Workbooks[0]; IWorksheet sheet = workBook.Worksheets[0]; sheet.InsertColumn(1, 1, ExcelInsertOptions.FormatDefault); var rowcount = this.sfDataGrid.RowGenerator.Items.Count; for (int i = 1; i < rowcount; i++) { sheet.Range["A" + (i + 1).ToString()].Number = i; } SaveFileDialog sfd = new SaveFileDialog { FilterIndex = 2, Filter = "Excel 97 to 2003 Files(*.xls)|*.xls|Excel 2007 to 2010 Files(*.xlsx)|*.xlsx|Excel 2013 File(*.xlsx)|*.xlsx" }; if (sfd.ShowDialog() == true) { using (Stream stream = sfd.OpenFile()) { if (sfd.FilterIndex == 1) workBook.Version = ExcelVersion.Excel97to2003; else if (sfd.FilterIndex == 2) workBook.Version = ExcelVersion.Excel2010; else workBook.Version = ExcelVersion.Excel2013; workBook.SaveAs(stream); } //Message box confirmation to view the created workbook. if (MessageBox.Show("Do you want to view the workbook?", "Workbook has been created", MessageBoxButton.YesNo, MessageBoxImage.Information) == MessageBoxResult.Yes) { //Launching the Excel file using the default Application.[MS Excel Or Free ExcelViewer] System.Diagnostics.Process.Start(sfd.FileName); } } }
The following screenshot illustrates the RowHeader displayed in WPF DataGrid (SfDataGrid),
The following screenshot illustrates exported Excel Sheet with RowHeader,
Take a moment to peruse the WPF DataGrid — Export To Excel documentation, where you can find about export to excel with code examples.
KB article: How to export the WPF DataGrid (SfDataGrid) to excel with RowHeader?
Requirements to run the demo
Visual Studio 2015 and above versions
- Remove From My Forums
-
Question
-
Hi,
I want to export the content of DataGrid in the WPF application to Excel. The content of the data grid will be loaded dynamically, on button click i have to export the datagrid data to excel. Can any one help me how to implement this
Answers
-
I have done this before on a style so that it applies to all datagrids using a context menu in the header. So basically create a resourcedictionary and create your style for the datagrid. in the header style add the context menu as so
<ContextMenu DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}"> <MenuItem Header="Export To Excel"> <MenuItem.Style> <Style TargetType="MenuItem"> <EventSetter Event="PreviewMouseDown" Handler="ctxExportCsv" /> </Style> </MenuItem.Style> </MenuItem> </ContextMenu>
then create the code behind file for the resource dictionary (just a cs file with same name as resource dictionary)
and then put the event to handle it.
void ctxExportCsv(object sender, MouseButtonEventArgs e) { var o = ((DataGridColumnHeader)((ContextMenu)((MenuItem)sender).Parent).DataContext).Column; DataGrid dg = o.GetDataGridParent(); dg.SelectAllCells(); dg.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader; ApplicationCommands.Copy.Execute(null, dg); dg.UnselectAllCells(); String result = (string)Clipboard.GetData(DataFormats.CommaSeparatedValue); try { StreamWriter sw = new StreamWriter("export.csv"); sw.WriteLine(result); sw.Close(); Process.Start("export.csv"); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
this will give any datagrid with your style a contextmenu on its header with an export to excel option.
hope that helps. if you don’t want on style just use the c# code and modify as appropriate.
Cheers
Andy
-
Proposed as answer by
Wednesday, April 3, 2013 7:16 AM
-
Marked as answer by
Min Zhu
Monday, April 8, 2013 5:24 AM
-
Proposed as answer by