Определите форматы ячеек (дата, валюта, пользовательские и т. Д.) В xlsx, используя OpenXml - PullRequest
0 голосов
/ 14 ноября 2018

Я использую OpenXml для анализа текста из xlsx файлов.

Простой текст и числа извлекаются, как и ожидалось, но все, что имеет форматирование ячеек, например date, currency или custom format не извлекаются согласно отображаемому тексту в Excel.Это не было бы проблемой, если бы я мог легко определить формат ячейки в коде и затем предпринять соответствующее действие, но я нигде не могу его найти!

Файл Example.xlsx содержит:


Ячейка A1 - формат даты * 14/03/2001

Ввод текста '14/11/2018' в ячейку A1 отображается как '14/11/2018'

МестныйПеременные:

c.CellValue = "43418"
c.CellValue.InnerText = "43418"
c.Prefix = "x"
c.StyleIndex ="2"
c.DataType Nothing
c.CellFormula Nothing

Обязательное значение = '14/11/2018'


Ячейка A2 - формат валюты (Символ £, 2 десятичных знака)

Ввод текста '2000' в ячейку A2 отображается как '£ 2000,00'

Локальные переменные:

c.CellValue = "2000"
c.CellValue.InnerText = "2000"
c.Prefix = "x"
c.StyleIndex = "3"
c.DataType Nothing
c.CellFormula Nothing

Обязательное значение = '£2,000.00'


Ячейка A3 - пользовательский формат «ABC -» @

При вводе текста «P-100» в ячейку A3 отображается «ABC-P-100»

LocalПеременные:

OpenXml Cell.CellValue = "P-100"
OpenXml Cell.CellValue.InnerText = "P-100"
OpenXml Cell.Prefix = "x"
OpenXml Cell.StyleIndex = "1"
OpenXml Cell.DataType = "s"
c.CellFormula Ничего

Обязательное значение = 'ABC-P-1000'


Вот мой код:

Public Shared Sub parseXLS(strFileName As String, sbTxtFromFile As StringBuilder)
    Call fncParseXLSXorXLSM(strFileName, sbTxtFromFile)
End Sub

Public Shared Function fncParseXLSXorXLSM(strFileName As String, sbTxtFromFile As StringBuilder) As StringBuilder

        sbTxtFromFile.Length = 0
        Dim intFirst As Integer = 1

        Try
            Using spreadsheetDocument__1 As SpreadsheetDocument = SpreadsheetDocument.Open(strFileName, False)
                Dim workbookPart As WorkbookPart = spreadsheetDocument__1.WorkbookPart
                Dim sharedStringItemsArray As SharedStringItem() = workbookPart.SharedStringTablePart.SharedStringTable.Elements(Of SharedStringItem)().ToArray()
                Dim sheets As DocumentFormat.OpenXml.Spreadsheet.Sheets = spreadsheetDocument__1.WorkbookPart.Workbook.Sheets

                ' For each sheet, display the sheet information.
                For Each sheet As DocumentFormat.OpenXml.OpenXmlElement In sheets
                    For Each attr As DocumentFormat.OpenXml.OpenXmlAttribute In sheet.GetAttributes()
                        Debug.Print("{0}: {1}", attr.LocalName, attr.Value)
                        If attr.LocalName = "name" Then
                            sbTxtFromFile.Append(attr.Value)
                        End If
                    Next

                Next

                For Each worksheetPart As WorksheetPart In workbookPart.WorksheetParts
                    Dim reader As OpenXmlReader = OpenXmlReader.Create(worksheetPart)
                    While reader.Read()
                        If reader.ElementType Is GetType(Cell) Then
                            Do
                                Dim c As Cell = DirectCast(reader.LoadCurrentElement(), Cell)

                                If c.DataType IsNot Nothing AndAlso c.DataType.Value.ToString = "SharedString" Then
                                    Dim ssi As SharedStringItem = sharedStringItemsArray(Integer.Parse(c.CellValue.InnerText))

                                    If Not ssi.Text Is Nothing Then
                                        If Not ssi.Text.Text Is Nothing Then
                                            If intFirst = 1 Then
                                                sbTxtFromFile.Append(ssi.Text.Text)
                                                intFirst = 2
                                            Else
                                                sbTxtFromFile.Append(Environment.NewLine & ssi.Text.Text)
                                            End If
                                        End If
                                    Else
                                        If Not ssi.InnerText Is Nothing Then
                                            If intFirst = 1 Then
                                                sbTxtFromFile.Append(ssi.InnerText)
                                                intFirst = 2
                                            Else
                                                sbTxtFromFile.Append(Environment.NewLine & ssi.InnerText)
                                            End If
                                        End If
                                    End If
                                Else
                                    If Not c.CellValue Is Nothing Then
                                        If intFirst = 1 Then
                                            sbTxtFromFile.Append(c.CellValue.InnerText)
                                            intFirst = 2
                                        Else
                                            sbTxtFromFile.Append(Environment.NewLine & c.CellValue.InnerText)
                                        End If
                                    End If
                                End If
                            Loop While reader.ReadNextSibling()
                        End If
                        If sbTxtFromFile.Length > 0 Then
                            sbTxtFromFile.Append(Environment.NewLine)
                        End If
                    End While
                Next

            End Using

        Catch ex As Exception
            If ex.Message Like "The process cannot access the file '*" Then 'File in use
                sbTxtFromFile.Append("|11readonly11|")
            ElseIf ex.Message Like "Could not find*" Then 'File in use
                sbTxtFromFile.Append("|11notfound11|")
            Else
                sbTxtFromFile.Append("|11cannotread11|")
            End If
        End Try

        Return sbTxtFromFile

    End Function

Есть идеи?

1 Ответ

0 голосов
/ 19 ноября 2018

Вы можете прочитать стиль ячейки на основе свойства StyleIndex, которое поможет вам определить форматирование, примененное к ячейке.

Используйте следующий метод в качестве примера и обойдите в зависимости от ваших потребностей:

Private Shared Sub ReadCellFormat(cell As Cell, stylesheet As Stylesheet)
    If cell.StyleIndex.HasValue Then
        Debug.Print("Style found for the cell:")
        If stylesheet.CellFormats.Count.Value > cell.StyleIndex.Value Then
            Dim format As CellFormat = stylesheet.CellFormats.ElementAt(cell.StyleIndex.Value)
            If format.NumberFormatId.HasValue AndAlso format.NumberFormatId.Value > 0 Then
                Dim numberFormat As NumberingFormat = stylesheet.NumberingFormats.Single(Function(x As NumberingFormat) x.NumberFormatId.Value = format.NumberFormatId.Value)
                Debug.Print($"Format code: {numberFormat.FormatCode}")
            End If
        End If
    End If
End Sub

PS: этот метод просто читает числовой формат для данной ячейки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...