Introduction
This article explains how to export the contents of a dataset with more than one table, to an Excel workbook in separate sheets. The article also helps to understand the basics behind the Excel application object and its usage for creating a Workbook and inserting Worksheets in it. The following code can however extend its functionalities by incorporating methods and procedures for formatting the written data like the cell background, font color, inserting formulas, etc.
Background
The need to write this code came up when one of my applications needed the same functionalities where my Stored Procedure returned two result sets which I stored in a dataset. The user wanted the two result sets to be displayed in two separate sheets in an Excel file. But the current method of Response.AddHeader ("content-disposition")
allowed me to write the output in one single sheet with the two result sets one below the other. After exploring the net and integration of a couple of techniques, I came up with a solution which could solve my purpose of creating an Excel file and then writing the data from the dataset tables in the Excel file.
Using the Code - Implementation
The code is pretty simple and straightforward. As a pre-requisite, you should have Excel installed on your system. I have used VB.NET as my base language. Although with a little modification you can always convert the existing code to C# too.
In order to start using the code, add a reference to the COM object Microsoft Excel Object Library. Since I had Microsoft Office 2003 installed on my system, it was Microsoft Excel 11.0 Object Library in my case. Now import the namespaces for the Excel library and InteropServices
into your code.
Imports Microsoft.Office.Interop
Imports System.Runtime.InteropServices.Marshal
We will need to import InteropServices
because the Microsoft Office code is still based on the old, unmanaged world and you need to use COM Interop to facilitate communication with it. Now copy the following code to your code-behind file to export the dataset tables to Excel. The function takes as parameter a DataSet
containing the DataTable
s.
Public Sub ExportToExcel(ByVal DS_MyDataset As DataSet)
Dim strFileName As String = _
AppDomain.CurrentDomain.BaseDirectory.Replace("/", "\")
strFileName = strFileName & "\MyExcelFile" & _
System.DateTime.Now.Ticks.ToString() ".xls"
Dim objExcel As Excel.Application
Dim objBooks As Excel.Workbooks, objBook As Excel.Workbook
Dim objSheets As Excel.Sheets, objSheet As Excel.Worksheet
Dim objRange As Excel.Range
Try
objExcel = New Excel.Application
objExcel.Visible = False
objExcel.DisplayAlerts = False
objBook = CType(objExcel.Workbooks.Add(), Excel. Workbook)
objBook.SaveAs(strFileName, Excel.XlFileFormat.xlWorkbookNormal)
objBooks = objExcel.Workbooks
objSheet = CType(objBooks(1).objSheets.Item(1), Excel.Worksheet)
objSheet.Name = "First Sheet"
objSheet.Range("A1","Z1").Font.Bold = True
objRange = objSheet.Cells
WriteData(DS_MyDataset.Tables(0), objCells)
objSheet.Range("A1","Z1").EntireColumn.AutoFit()
objSheet.SaveAs(strFileName)
objBook = objBooks.Item(1)
objSheets = objBook.Worksheets
objSheet = CType(objSheets.Item(2), Excel.Worksheet)
objSheet.Name = "Second Sheet"
objSheet.Range("A1","Z1").Font.ColorIndex = 3
objRange = objSheet.Cells
WriteData(DS_MyDataset.Tables(1), objCells)
objSheet.Range("A1","Z1").EntireColumn.AutoFit()
objSheet.SaveAs(strFileName)
Catch ex As Exception
Response.Write(ex.Message)
Finally
objExcel.Quit()
ReleaseComObject(objRange)
ReleaseComObject(objSheet)
ReleaseComObject(objSheets)
ReleaseComObject(objBook)
ReleaseComObject(objBooks)
ReleaseComObject(objExcel)
objExcel = Nothing
objBooks = Nothing
objBook = Nothing
objSheets = Nothing
objSheet = Nothing
objRange = Nothing
System.GC.Collect()
End Try
End Sub
Private Function WriteData(ByVal DT_DataTable As DataTable, _
ByVal objCells As Excel.Range) As String
Dim iRow As Integer, iCol As Integer
For iCol = 0 To DT_DataTable.Columns.Count - 1
objCells(1, iCol + 1) = DT_DataTable.Columns(iCol).ToString
Next
For iRow = 0 To DT_DataTable.Rows.Count - 1
For iCol = 0 To DT_DataTable.Columns.Count - 1
objCells(iRow + 2, iCol + 1) = DT_DataTable.Rows(iRow)(iCol)
Next
Next
End Function
Pros and Cons
Pros:
- Code can be used as a component to export formatted reports to Excel.
- The code is very small and can be modified as per user requirements for getting formatted output on Excel sheets in a presentable format.
Cons:
- The code uses Excel Object Library which is required at the development server.
- Since the code creates objects of COM components through Interop services, if the components are not efficiently released, it may result in memory leakage.
Conclusion
You can see that the above code is self explanatory and quite understandable. The code can further be enhanced by formatting the written data like the background of the cells, adding gridlines to the Excel sheet, etc. We can even add more sheets to the file if the dataset contains more than three tables since the default workbook has three sheets. The above code is just a sample of what all can be done with the Excel object. More enhanced exception handling can be done by catching more specific exceptions. Enjoy and happy coding!!!!