Dealing With Excel Sheets

This article explains how to read from an Excel sheet, create an Excel sheet and write into an Excel sheet (both .xls and .xlsx files) using C#.

.xls vs .xlsx

  • The default format for a spreadsheet is .xls
  • Microsoft Excel has .xls as the default format from the beginning. Microsoft 2007 changed the default fromat for Microsoft Excel to .xlsx.
  • Xlsx is a XML based file format and the information is stored in XML format. Xls is based on the Binary interchange File Format (BIFF) and the information is stored in binary format.

There are some packages available, using which we can deal with Excel sheets. Some of them are:

  • ExcelLibrary: Only .xls files can be read. ExcelLibrary 1.3.3 is commercial.
  • ExcelPackage: Only .xlsx files can be read. It's performance is slow.
  • Microsoft.Office.Interop.Excel: Microsoft office should be installed on the server.
  • GemBox.Spreadsheet: It has a limitation on the number of sheets per workbook and rows per sheet. The maximum number of rows allowed per sheet is 150 and the number of sheets allowed per workbook is 5.
  • Bytescout.Spreadsheet: Paid DLL, the free one is a trial version.

We will use the “ExcelDataReader” package for reading the Excel sheet and ExcelLibrary.dll for creating the Excel sheet. Both of these are free.

Install ExcelDataReader using the Package Manager Console.

Click on Tools then select Library Package Manager -> Package Manager Console (if you don't have Nuget Package Manager installed, download from https://visualstudiogallery.msdn.microsoft.com/27077b70-9dad-4c64-adcf-c7cf6bc9970c & install).

Run the following command in the Package Manager Console to install ExcelDataReader.

PM> Install-Package ExcelDataReader

Here our logic will be: Create a binary reader (for .xls) or XML reader (for .xlsx) based on the file format. For reading from a single sheet, read from the reader and to read from multiple sheets, convert this reader to a DataSet and read the data.

Let's see a demo app

Create an Empty web application. Add a web form with an ASP Upload control (to upload an Excel workbook), a textarea (for sheet names) and a button control.

  1. <div>  
  2.     <asp:FileUpload runat="server" ID="FileUploader"/><br/>  
  3.         <textarea id="txtSheetNames" runat="server"><br>  
  4.         <asp:button runat="server" onclick="ProcessExcel" text="Continue">  
  5.   
  6. </asp:button> 

Now, in code behind:

  1. // Save Uploaded file on to server  
  2.             const string FilePath = @"E:\DemoProjects\Excel\UploadedFiles\";  
  3.             var FileName = FileUploader.PostedFile.FileName + "_" +  
  4.                            DateTime.Now.ToString("yyyyMMddTHHmmssZ") + FileExtension;  
  5.             var FullPath = Path.Combine(FilePath, FileName);  
  6.             Request.Files[0].SaveAs(FullPath);  
  7.   
  8. // Initialize an instance of FileStream  
  9.             var Stream = new FileStream(new FileInfo(FullPath).ToString(), FileMode.Open,  
  10.                         FileAccess.Read);  
  11.   
  12. // Create an instance of type IExcelDataReader  
  13. var ExcelReader = string.Equals(FileExtension,".xlsx")  
  14.                 //Reading from a OpenXml Excel file (2007 format; *.xlsx)  
  15.                 ? ExcelReaderFactory.CreateOpenXmlReader(Stream)  
  16.                 //Reading from a binary Excel file (97-2003 format; *.xls)  
  17.                 : ExcelReaderFactory.CreateBinaryReader(Stream);  
  18.   
  19. To read from single sheet,  
  20. //Traverse through the reader  
  21. while (ExcelReader.Read())  
  22.                 {  
  23.                     //Operate on each row & create list for response excel sheet  
  24.                 }  
  25.   
  26.   
  27. To read from multiple sheets by sheet name,  
  28. //Convert Reader to DataSet  
  29. var MembersDataSet = ExcelReader.AsDataSet();  
  30.   
  31. var TempWorkSheet = MembersDataSet.Tables[SheetName];  
  32.   
  33.                     if (TempWorkSheet != null &&  
  34.                         TempWorkSheet.Columns.Count >= DataColumnsCount)  
  35.                     {  
  36.                         var TempSheetRows = from DataRow TempRow in TempWorkSheet.Rows  
  37.                             select TempRow;  
  38.                 // Operate on each row & create list for response from current sheet  
  39.             } 

Now, let's create a spreadsheet.

If you are reading from a single sheet (by default the first one in the workbook), create a list with response data. Convert this list to a table (you can rename the table also). Add this table to a DataSet. Convert this DataSet to an Excel workbook.

If you are reading from multiple Excel sheets in a workbook and want to show a response in multiple sheets (a separete response sheet for each uploaded sheet), create a list for each sheet data and convert the list to a table. Add these tables to the DataSet and convert this DataSet to an Excel workbook.

For converting a list to a DataTable:

  1. private static DataTable ToDataTable<T>(IEnumerable<T> LstItems)  
  2.         {  
  3.             var ObjDataTable = new DataTable(typeof(T).Name);  
  4.   
  5.             //Get all the properties  
  6.             var PropertyInfos = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);  
  7.             foreach (var Prop in PropertyInfos)  
  8.             {  
  9.                 //Setting column names as Property names  
  10.                 ObjDataTable.Columns.Add(Prop.Name);  
  11.             }  
  12.             foreach (T Item in LstItems)  
  13.             {  
  14.                 var Values = new object[PropertyInfos.Length];  
  15.                 for (var I = 0; I < PropertyInfos.Length; I++)  
  16.                 {  
  17.                     //inserting property values to datatable rows  
  18.                     Values[I] = PropertyInfos[I].GetValue(Item, null);  
  19.                 }  
  20.                 ObjDataTable.Rows.Add(Values);  
  21.             }  
  22.             //put a breakpoint here and check datatable  
  23.             return ObjDataTable;  
  24.         } 

For converting a DataSet to a workbook, use ExcelLibrary. You can download ExcelLibrary.dll from https://code.google.com/p/excellibrary/downloads/detail?name=ExcelLibrary.dll&can=2&q=

  1. private static Workbook DataSetToExcel(DataSet ObjDataSet)  
  2.         {  
  3.             var ObjWorkBook = new Workbook();  
  4.             foreach (DataTable ObjDataTable in ObjDataSet.Tables)  
  5.             {  
  6.                 var ResponseRowCount = 0;  
  7.                 var ObjWorkSheet = new Worksheet(ObjDataTable.TableName);  
  8.                 PopulateHeader(ObjWorkSheet);  
  9.                 foreach (DataRow ObjDataRow in ObjDataTable.Rows)  
  10.                 {  
  11.                     ResponseRowCount++;  
  12.                     ObjWorkSheet.Cells[ResponseRowCount, 0] =  
  13.                         new Cell(ObjDataRow["FirstName"].ToString());  
  14.                     ObjWorkSheet.Cells[ResponseRowCount, 1] =  
  15.                         new Cell(ObjDataRow["LastName"].ToString());  
  16.                     ObjWorkSheet.Cells[ResponseRowCount, 2] =  
  17.                         new Cell(ObjDataRow["Address"].ToString());  
  18.                     ObjWorkSheet.Cells[ResponseRowCount, 3] =  
  19.                         new Cell(ObjDataRow["Comment"].ToString());  
  20.                 }  
  21.                 ObjWorkBook.Worksheets.Add(ObjWorkSheet);  
  22.             }  
  23.             return ObjWorkBook;  
  24.         } 

Check the uploaded code for a better understanding.