//
you're reading...
Drybridge Activities, Windows Application, XML

OpenXML SpreadsheetML Simple Spreadsheet Creation

OpenXML SpreadsheetML Simple Spreadsheet Creation

Simple WinForms for the creation of an Excel Spreadsheet using the Microsoft Office OpenXML 2.0 SDK.

  • Requires Reference to DocumentFormat.OpenXML and I believe WindowsBase. Project is a simple WinForm with a button.

Imports DocumentFormat.OpenXml
Imports DocumentFormat.OpenXml.Packaging
Imports DocumentFormat.OpenXml.Spreadsheet
Imports System.IO

Public Class Form1
Private mOutputDir As String = My.Computer.FileSystem.SpecialDirectories.AllUsersApplicationData
Private mFileName As String = “Test.xlsx”
Private mFileLocation As String = Path.Combine(mOutputDir, mFileName)
Private newSpreadSheet As SpreadsheetDocument

Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click

     Dim wsp As WorksheetPart = Spreadsheet_Create()
     InsertText(wsp, “hello world”)
     Spreadsheet_Close()
End Sub

Private Function Spreadsheet_Create() As WorksheetPart
     ‘Delete the file if exists
     If My.Computer.FileSystem.FileExists(mFileLocation) Then
          My.Computer.FileSystem.DeleteFile(mFileLocation)
     End If

     ‘Create spreadsheet
     newSpreadSheet = SpreadsheetDocument.Create(mFileLocation, SpreadsheetDocumentType.Workbook)

     ‘Add WorkbookPart & Workbook
     Dim newWorkbookPart As WorkbookPart = newSpreadSheet.AddWorkbookPart
     newWorkbookPart.Workbook = New Workbook()

     ‘Add Worksheet
     Return InsertWorksheet(newSpreadSheet.WorkbookPart)
End Function

Private Sub Spreadsheet_Close()
     newSpreadSheet.WorkbookPart.Workbook.Save()
     newSpreadSheet.Close()
End Sub

Public Sub InsertText(ByVal wsp As WorksheetPart, ByVal text As String)
     ‘ Get the SharedStringTablePart. If it does not exist, create a new one.
     Dim shareStringPart As SharedStringTablePart
     If (newSpreadSheet.WorkbookPart.GetPartsOfType(Of SharedStringTablePart).Count() > 0) Then
          shareStringPart = newSpreadSheet.WorkbookPart.GetPartsOfType(Of SharedStringTablePart).First()
     Else
          shareStringPart = newSpreadSheet.WorkbookPart.AddNewPart(Of SharedStringTablePart)()
     End If

     ‘ Insert the text into the SharedStringTablePart.
     Dim index As Integer = InsertSharedStringItem(text, shareStringPart)

     ‘ Insert cell A1 into the new worksheet.
     Dim cell As Cell = InsertCellInWorksheet(“A”, 1, wsp)

     ‘ Set the value of cell A1.
     cell.CellValue = New CellValue(index.ToString)
     cell.DataType = New EnumValue(Of CellValues)(CellValues.SharedString)

     ‘ Save the new worksheet.
     wsp.Worksheet.Save()
End Sub

‘ Given text and a SharedStringTablePart, creates a SharedStringItem with the specified text
‘ and inserts it into the SharedStringTablePart. If the item already exists, returns its index.
Private Function InsertSharedStringItem(ByVal text As String, ByVal shareStringPart As SharedStringTablePart) As Integer
     ‘If the part does not contain a SharedStringTable, create one
     If (shareStringPart.SharedStringTable Is Nothing) Then
          shareStringPart.SharedStringTable = New SharedStringTable
     End If
   
     Dim i As Integer = 0
     ‘Iterate through all the items in the SharedStringTable. If the text already exists, return its index
     For Each item As SharedStringItem In shareStringPart.SharedStringTable.Elements(Of SharedStringItem)()
          If (item.InnerText = text) Then
               Return i
          End If
          i = (i + 1)
     Next

     ‘The text does not exist in the part. Create the SharedStringItem and return its index
     shareStringPart.SharedStringTable.AppendChild(New SharedStringItem(New DocumentFormat.OpenXml.Spreadsheet.Text(text)))
     shareStringPart.SharedStringTable.Save()
     Return i
End Function

‘Given a WorkbookPart, inserts a new worksheet.
Private Function InsertWorksheet(ByVal workbookPart As WorkbookPart) As WorksheetPart

     ‘ Add a new worksheet part to the workbook.
     Dim newWorksheetPart As WorksheetPart = _
                    workbookPart.AddNewPart(Of WorksheetPart)()
     newWorksheetPart.Worksheet = New Worksheet(New SheetData)
     newWorksheetPart.Worksheet.Save()

     ‘Get a unique ID for the new worksheet
     Dim sheetId As UInteger = 1
     Dim sheets As New Sheets
     If newSpreadSheet.WorkbookPart.Workbook.GetFirstChild(Of Sheets)() IsNot Nothing Then
          sheets = newSpreadSheet.WorkbookPart.Workbook.GetFirstChild(Of Sheets)()
          ‘Not sure if this check is required, possible an hanger-on from previous attempts
          If (sheets.Elements(Of Sheet).Count > 0) Then
               sheetId = sheets.Elements(Of Sheet).Select(Function(s) s.SheetId.Value).Max + 1
          End If
     End If

     Dim relationshipId As String = _
                    newSpreadSheet.WorkbookPart.GetIdOfPart(newWorksheetPart)
     Dim sheetName As String = (“Sheet” + sheetId.ToString())

     ‘ Add the new worksheet and associate it with the workbook.
     Dim sheet As Sheet = New Sheet
     sheet.Id = relationshipId
     sheet.SheetId = sheetId
     sheet.Name = sheetName
     sheets.Append(sheet)
     If newSpreadSheet.WorkbookPart.Workbook.GetFirstChild(Of Sheets)() Is Nothing Then
          newSpreadSheet.WorkbookPart.Workbook.AppendChild(Of Sheets)(sheets)
     End If
     workbookPart.Workbook.Save()

     Return newWorksheetPart

End Function

‘ Given a column name, a row index, and a WorksheetPart, inserts a cell into the worksheet.
‘ If the cell already exists, return it.
Private Function InsertCellInWorksheet(ByVal columnName As String, ByVal rowIndex As UInteger, ByVal wsp As WorksheetPart) As Cell
     Dim worksheet As Worksheet = wsp.Worksheet
     Dim sheetData As SheetData = worksheet.GetFirstChild(Of SheetData)()
     Dim cellReference As String = (columnName + rowIndex.ToString())
     ‘ If the worksheet does not contain a row with the specified row index, insert one.
     Dim row As Row
     If (sheetData.Elements(Of Row).Where(Function(r) r.RowIndex.Value = rowIndex).Count() <> 0) Then
          row = sheetData.Elements(Of Row).Where(Function(r) r.RowIndex.Value = rowIndex).First()
     Else
          row = New Row()
          row.RowIndex = rowIndex
          sheetData.Append(row)
     End If
     ‘ If there is not a cell with the specified column name, insert one.
     If (row.Elements(Of Cell).Where(Function(c) c.CellReference.Value = columnName + rowIndex.ToString()).Count() > 0) Then
          Return row.Elements(Of Cell).Where(Function(c) c.CellReference.Value = cellReference).First()
     Else
          ‘ Cells must be in sequential order according to CellReference. Determine where to insert the new cell.
          Dim refCell As Cell = Nothing
          For Each cell As Cell In row.Elements(Of Cell)()
                If (String.Compare(cell.CellReference.Value, cellReference, True) > 0) Then
                     refCell = cell
                     Exit For
                End If
          Next
          Dim newCell As Cell = New Cell
          newCell.CellReference = cellReference
          row.InsertBefore(newCell, refCell)
          worksheet.Save()
          Return newCell
     End If
End Function
End Class

About art colman

XML tools and consulting for standards development.

Discussion

7 thoughts on “OpenXML SpreadsheetML Simple Spreadsheet Creation

  1. Thanks -that was rather userful!

    Jolly good show.

    Posted by Alphonso | April 2, 2009, 5:09 pm
  2. Thanks for your comment. I’ve always been of the opinion that getting the initial iteration of a project up and running is the hardest part. With the focus on RAD and Agile approaches it is also the most important.

    colman@drybridge.com

    Posted by art colman | April 3, 2009, 7:58 am
  3. Thanks for the code ! Is it possible to add a code where you change the cellstyle (Fontname, Fontsize, BorderStyle,Backcolor ..)
    I search all the internet, I could’nt find anything . The help file of the Open XML SDK 2.0 is simply ridiculous.

    Greetings

    Zash

    Posted by Lux Sacha | April 16, 2009, 8:23 am
  4. Thanks so very much for your kind comments.
    I have posted some information at https://drybridge.wordpress.com/2009/04/16/openxml-spreadsheetml-cell-formatting/ that should provide some help.

    Posted by art colman | April 16, 2009, 10:09 am
  5. Thank for this! Work with SharedStringTable was very useful for me. And little question – do you use linq? How can I check for item in SharedStringTable with linq and without ‘For Each’?

    Posted by Sergey Shatzkiy | August 1, 2009, 6:48 am
  6. Interesting idea Sergey. I’ll do some more detailed investigation of linq as it should simplify the selection process.

    Art Colman Drybridge Technologies http://www.drybridge.com LinkedIn Profile http://www.linkedin.com/in/artcolman

    Posted by art colman | August 1, 2009, 7:18 pm
  7. Was looking for this since 2 weeks,already seen lot of SpreadsheetMl work in C#,on vb.net you are first,Millions thanks

    Posted by Amol Awate | June 8, 2012, 4:52 am

Leave a comment