ClosedXML is a fine library for exporting data to Excel. It is very simple to use and fast enough for smaller sets of data. But it also has some cons:
1.) It uses OpenXML – that is not a con by itself, but the problem appears when you want to save file as Xls. XML concept of Office files was presented with Office 2007 and is not compatible with previous versions of Office. But if you really need Xls, you can create Excel file using ClosedXML and than open and save it as Xls using Interop. That is only possible if you are exporting data on client side with installed PIA and Office. It is strongly advised against using Interop on server side due to the fact that Office is client side application!
2.) It is very slow for big datasets (more than few 10 thousand rows). For exporting big datasets you should use OpenXML (maybe I will talk about that in one of my next posts).
3.) On project’s CodePlex site it is written (quote): “ClosedXML makes it easier for developers to create Excel 2007/2010 files.”. But I believe Excel 2013 and newer should also open files generated with ClosedXML (haven’t tested it though).
Firstly you have to add reference to ClosedXML. You can do that using NuGet Package Manager or you can download ClosedXML DLL from CodePlex and add a reference to your project.
You also need to add a namespace to your CS file (using ClosedXML.Excel;).
Using ClosedXML you can set specific cell values, you can insert data from DataTable or from some other collection. In this post I will show you how to create generic function, which inserts data to Excel from IEnumerable of objects. I will pass column titles in separate List of string arrays.
Info: I could probably set column titles using descriptors on object properties – something like this:
[MyAttribute("First property")] public string FstProperty { get {....} set {....} }
But for the sake of the example I won’t complicate – I will pass the titles to the function in a separate List.
Our function should look something like this:
public byte[] ExportToExcel<T>(IEnumerable<T> data, string worksheetTitle, List<string[]> titles) { var wb = new XLWorkbook(); //create workbook var ws = wb.Worksheets.Add(worksheetTitle); //add worksheet to workbook ws.Cell(1, 1).InsertData(titles); //insert titles to first row if (data != null && data.Count() > 0) { //insert data to from second row on ws.Cell(2, 1).InsertData(data); } //save file to memory stream and return it as byte array using (var ms = new MemoryStream()) { wb.SaveAs(ms); return ms.ToArray(); } }
And that is it! If we wish to add some special styling to our heading row, we have to modify our code snippet a little:
var rangeTitle = ws.Cell(1, 1).InsertData(titles); //insert titles to first row rangeTitle.AddToNamed("Titles"); var titlesStyle = wb.Style; titlesStyle.Font.Bold = true; //font must be bold titlesStyle.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; //align text to center titlesStyle.Fill.BackgroundColor = XLColor.Red; //background must be red wb.NamedRanges.NamedRange("Titles").Ranges.Style = titlesStyle; //attach style to the range
We can also adjust column width to maximum content width using function AdjustToContents right before we save the file:
ws.Columns().AdjustToContents();
Thank you Marko
Y como ejecuto esa función en mi controlador?
Thank god for google translate (I don’t speak spanish :)). Well, easy – you can put this function in your controller and call it from action method. But it would be cleaner to put in some helper file (e.g. ExcelHelper.cs).
I am Exporting more than 2.5 lack records with in 60 sec using ClosedXML
And, was getting problem for openXml
Sorry, man. I don’t really understand your question. 🙁
Hi there Marko
thank you for your article.
A question:
public byte[] ExportToExcel(IEnumerable data, string worksheetTitle, List titles)
See the signature of the above.
Do you mean to have the third parameter as a list of string arrays, or simply as a list of strings?
The third parameter is a list of string array. List is for rows, array for columns – like 2-D array or something.
You actually might want to check out the https://zetexcel.com/. I personally use for my cross-platform application.
is there a way to get data from excel export it into closedxml? not by doing it in excel thou
I’m sorry, I don’t fully understand the question. Are you talking about import from Excel?