打开Open XML创建的Excel文件时出错

时间:2015-01-15 16:29:55

标签: xml excel openxml

我已经开始使用Open XML创建一个Excel文件,以便向其中添加一些数据。我包含的示例文件是我在网上找到的示例的修改版本。它创建了excel文件但是当我尝试打开它时,它给了我三个错误。我怀疑最后两个错误是由于为标题单元格添加了 StyleIndex ,但是当我打开任何Excel文件时,最近出现了第一个错误。

1-无法使用对象链接和嵌入。

2- Excel在'SheetPInfo.xlsx'中发现了不可读的内容。您要恢复此工作簿的内容吗?如果您信任此工作簿的来源,请单击“是”。

3-Excel能够通过修复或删除不可读的内容来打开文件。 修复的记录:来自/xl/worksheets/sheet.xml部分的单元信息

在关闭最后一条错误消息后,我也在文件中获取数据/数组,但StyleIndex(更大的字体)没有出现在标题单元格'Last Name'中。

可能出错了什么?当我在网上搜索时,行的顺序对于Excel非常重要,所以我想也许我的StyleIndex相关行可能在错误的位置。

非常感谢任何帮助。

Imports System.Linq
Imports DocumentFormat.OpenXml
Imports DocumentFormat.OpenXml.Packaging
Imports DocumentFormat.OpenXml.Spreadsheet
Public Class TestEcel10
    Inherits System.Web.UI.Page

    Private mFileName As String = "SheetPInfo.xlsx"
    Private mFileLocation As String = "c:\Contracts\" & mFileName
    Private newSpreadSheet As SpreadsheetDocument

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    End Sub
    Private Sub btnExportToExcel_Click(sender As Object, e As EventArgs) Handles btnExportToExcel.Click

        Dim wsp As WorksheetPart = Spreadsheet_Create()

        Dim PInfoArr(2, 3) As String
        PInfoArr(0, 0) = "Frank"
        PInfoArr(0, 1) = "Baker"
        PInfoArr(0, 2) = "2/18/1977"
        PInfoArr(0, 3) = "Frank"

        PInfoArr(1, 0) = "William"
        PInfoArr(1, 1) = "Cook"
        PInfoArr(1, 2) = "2/18/1987"
        PInfoArr(1, 3) = "Bill"

        PInfoArr(2, 0) = "Nancy"
        PInfoArr(2, 1) = "Williams"
        PInfoArr(2, 2) = "2/18/1973"
        PInfoArr(2, 3) = "Nancy"

        InsertText(wsp, PInfoArr)
        Spreadsheet_Close()
    End Sub   'End of btnExportToExcel_Click 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   'End of Spreadsheet_Create function

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

    Public Sub InsertText(ByVal wsp As WorksheetPart, ByVal PInfoArray 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

        Dim index As Integer = 0
        Dim i As Integer = 0
        Dim j As Integer = 0
        Dim cell As Cell

        'Inserting column headings:

        ' Insert the text into the SharedStringTablePart.
        index = InsertSharedStringItem("First Name", shareStringPart)
        ' Insert cell A1 into the new worksheet.
        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)

        ' Insert the text into the SharedStringTablePart.
        index = InsertSharedStringItem("Last Name", shareStringPart)
        Dim styleIndex As UInt32Value = Convert.ToInt32("36")
        ' Insert cell A1 into the new worksheet.
        cell = InsertCellInWorksheet("B", 1, wsp)
        ' Set the value of cell A1.
        cell.CellValue = New CellValue(index.ToString)
        cell.StyleIndex = styleIndex
        cell.DataType = New EnumValue(Of CellValues)(CellValues.SharedString)

        ' Insert the text into the SharedStringTablePart.
        index = InsertSharedStringItem("Birth Date", shareStringPart)
        ' Insert cell A1 into the new worksheet.
        cell = InsertCellInWorksheet("C", 1, wsp)
        ' Set the value of cell A1.
        cell.CellValue = New CellValue(index.ToString)
        cell.DataType = New EnumValue(Of CellValues)(CellValues.SharedString)

        ' Insert the text into the SharedStringTablePart.
        index = InsertSharedStringItem("Nick Name", shareStringPart)
        ' Insert cell A1 into the new worksheet.
        cell = InsertCellInWorksheet("D", 1, wsp)
        ' Set the value of cell A1.
        cell.CellValue = New CellValue(index.ToString)
        cell.DataType = New EnumValue(Of CellValues)(CellValues.SharedString)

        'For column data we start from index 2 and increase it as we go to the next row
        Dim Rowindex As Integer = 2
        Dim ColumnLetter As String = "A"

        'Inserting column data:
        For i = 0 To UBound(PInfoArray, 1)

            For j = 0 To UBound(PInfoArray, 2)

                ' Insert the text into the SharedStringTablePart.
                index = InsertSharedStringItem(PInfoArray(i, j), shareStringPart)
                'Set the 
                If j = 0 Then
                    ColumnLetter = "A"
                ElseIf j = 1 Then
                    ColumnLetter = "B"
                ElseIf j = 2 Then
                    ColumnLetter = "C"
                ElseIf j = 3 Then
                    ColumnLetter = "D"
                End If
                ' Insert cell A1 into the new worksheet.
                cell = InsertCellInWorksheet(ColumnLetter, Rowindex, wsp)
                ' Set the value of cell A1.
                cell.CellValue = New CellValue(index.ToString)
                cell.DataType = New EnumValue(Of CellValues)(CellValues.SharedString)

                If ColumnLetter = "D" Then
                    Rowindex = Rowindex + 1
                End If
            Next
        Next

        ' Save the new worksheet.
        wsp.Worksheet.Save()
    End Sub   'End of InsertText 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   'End of InsertSharedStringItem 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   'End of InsertWorksheet 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 of InsertCellInWorksheet function

1 个答案:

答案 0 :(得分:0)

最后,我找到了一个解决方案,将我的数据放入Excel文件中,没有任何错误!我从http://www.codeproject.com/Tips/765068/Complete-Open-XML-Spreadsheet-in-VB下载了.zip文件 由于它的Visual Studio版本与我的版本不同,我不得不从下载的文件夹中复制其openXMLExcelCreator类并将其粘贴到我的项目中。然后我将其“doStuff”子添加到我的网页上,使用不同的名称并修改它以显示我想要的标题和数据库中的数据到单元格中。我还设法改变了标题行和替代行的背景,以便于搜索。