For this example we are going to create a Excel 2007 spreadsheet using the Microsoft OpenXml Sdk and Linq to XML.
To start with lets create a new Windows forms app which targets the .Net Framework 3.5. Add a Linq to Sql design surface to your project and name it Northwind and drag the Northwind Products table on to the surface. On the windows form I added a DataGridview to display the data we are going to export to excel. We also need a button named btnExport on the form.
To create a excel spreadsheet we need to use the openxml sdk to create a spreadsheet document, workbook, worksheet, and a string table.
Using doc = SpreadsheetDocument.Create("Export.xlsx", SpreadsheetDocumentType.Workbook)
Dim workbook = doc.AddWorkbookPart
Dim stringTable = workbook.AddNewPart(Of SharedStringTablePart)()
Dim worksheet = workbook.AddNewPart(Of WorksheetPart)()
The worksheet, workbook, and string table are xml documents contained inside a package. Before we get to far we need to import a few xml namespaces
Imports <xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
Imports <xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
Now that we imported the name space we can use some of the new xml features in VB 2008 to create the xml documents. Since we are not using a string table we just need a blank xml file
Dim xmlStringTable = <sst></sst>
The workbook xml needs to relate the spreadsheet with its id
Dim xmlWorkbook = <workbook>
<sheets>
<sheet name="Exported" sheetId="1" r:id=<%= sheetId %>></sheet>
</sheets>
</workbook>
Note the <%= sheetId %> allows you to get data from a variable
Finally we need to create the worksheet. In the worksheet we set the column widths and use a linq query to populate the data.
Dim xmlWorkSheet = <worksheet>
<sheetFormatPr defaultRowHeight="15"/>
<cols>
<col min="1" max="1" width="30" bestFit="1" customWidth="1"/>
<col min="2" max="2" width="10" bestFit="1" customWidth="1"/>
</cols>
<sheetData>
<row>
<c t="inlineStr">
<is>
<t>Product Name</t>
</is>
</c>
<c t="inlineStr">
<is>
<t>Unit Price</t>
</is>
</c>
</row>
<%= From p In db.Products Select _
<row>
<c t="inlineStr">
<is>
<t><%= p.ProductName %></t>
</is>
</c>
<c>
<v><%= p.UnitPrice %></v>
</c>
</row> %>
</sheetData>
</worksheet>
Here is the function for writing the xml to the file
Sub WriteXmlToPart(ByVal part As OpenXmlPart, ByVal x As XElement)
Dim fs As New IO.StreamWriter(part.GetStream, New System.Text.UTF8Encoding)
Dim xmlWriter As New Xml.XmlTextWriter(part.GetStream, New UTF8Encoding)
xmlWriter.Formatting = Xml.Formatting.Indented
Dim enc As New UTF8Encoding
xmlWriter.WriteStartDocument()
x.WriteTo(xmlWriter)
xmlWriter.WriteEndDocument()
xmlWriter.Flush()
xmlWriter.Close()
End Sub
Here is the complete listing for program
Imports Microsoft.Office.DocumentFormat.OpenXml.Packaging
Imports System.Text
Imports <xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
Imports <xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
Public Class Form1
Dim bs As New BindingSource
Dim db As New NorthwindDataContext
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
bs.DataSource = From p In db.Products _
Select p.ProductName, p.UnitPrice
DataGridView1.DataSource = bs
End Sub
Private Sub btnExport_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExport.Click
Using doc = SpreadsheetDocument.Create("Export.xlsx", SpreadsheetDocumentType.Workbook)
Dim workbook = doc.AddWorkbookPart
Dim stringTable = workbook.AddNewPart(Of SharedStringTablePart)()
Dim worksheet = workbook.AddNewPart(Of WorksheetPart)()
Dim sheetId = workbook.GetIdOfPart(worksheet)
'create the string table
Dim xmlStringTable = <sst></sst>
WriteXmlToPart(stringTable, xmlStringTable)
'create the workbook
Dim xmlWorkbook = <workbook>
<sheets>
<sheet name="Exported" sheetId="1" r:id=<%= sheetId %>></sheet>
</sheets>
</workbook>
WriteXmlToPart(workbook, xmlWorkbook)
'create the spreadsheet
Dim xmlWorkSheet = <worksheet>
<sheetFormatPr defaultRowHeight="15"/>
<cols>
<col min="1" max="1" width="30" bestFit="1" customWidth="1"/>
<col min="2" max="2" width="10" bestFit="1" customWidth="1"/>
</cols>
<sheetData>
<row>
<c t="inlineStr">
<is>
<t>Product Name</t>
</is>
</c>
<c t="inlineStr">
<is>
<t>Unit Price</t>
</is>
</c>
</row>
<%= From p In db.Products Select _
<row>
<c t="inlineStr">
<is>
<t><%= p.ProductName %></t>
</is>
</c>
<c>
<v><%= p.UnitPrice %></v>
</c>
</row> %>
</sheetData>
</worksheet>
WriteXmlToPart(worksheet, xmlWorkSheet)
End Using
End Sub
Sub WriteXmlToPart(ByVal part As OpenXmlPart, ByVal x As XElement)
Dim fs As New IO.StreamWriter(part.GetStream, New System.Text.UTF8Encoding)
Dim xmlWriter As New Xml.XmlTextWriter(part.GetStream, New UTF8Encoding)
xmlWriter.Formatting = Xml.Formatting.Indented
Dim enc As New UTF8Encoding
xmlWriter.WriteStartDocument()
x.WriteTo(xmlWriter)
xmlWriter.WriteEndDocument()
xmlWriter.Flush()
xmlWriter.Close()
End Sub
End Class