【问题标题】:How to retrieve complex excel file with merged cells and save as xml file using vb.net?如何使用合并单元格检索复杂的 Excel 文件并使用 vb.net 保存为 xml 文件?
【发布时间】:2015-09-19 11:05:58
【问题描述】:

我有这个可以检索excel文件并保存为xml文件。

Imports Microsoft.Office.Interop.Excel
Imports System.Xml
Imports System.IO

Module Module1
Sub Main()
    Try
        Dim excel As Application = New Application
        Dim filename As String = "person"
        Dim file_extension As String
        Dim path As String = "C:\Users\"
        Dim w As Workbook
        Try
            file_extension = "xlsx"
            w = excel.Workbooks.Open(path & filename + "." & file_extension)
        Catch ex As Exception
            file_extension = "xls"
            w = excel.Workbooks.Open(path & filename + "." & file_extension)
        End Try

        For i As Integer = 1 To w.Sheets.Count
            Dim sheet As Worksheet = w.Sheets(i)
            Dim r As Range = sheet.UsedRange
            Dim array(,) As Object = r.Value(XlRangeValueDataType.xlRangeValueDefault)

            If array IsNot Nothing Then

                Dim bound0 As Integer = array.GetUpperBound(0)
                Dim bound1 As Integer = array.GetUpperBound(1)

                Dim settings As XmlWriterSettings = New XmlWriterSettings()
                settings.Indent = True

                Using writer As XmlWriter = XmlWriter.Create(filename + ".xml", settings)
                    writer.WriteStartDocument()
                    writer.WriteStartElement(filename)
                    For j As Integer = 2 To bound0
                        writer.WriteStartElement(sheet.Name)
                        For x As Integer = 1 To bound1
                            writer.WriteElementString(array(1, x), array(j, x))
                        Next
                        writer.WriteEndElement()
                    Next
                    writer.WriteEndElement()
                    writer.WriteEndDocument()
                End Using
            End If
        Next
        w.Close()
    Catch ex As Exception
        Console.WriteLine("MS Excel file is invalid.")
        Console.WriteLine(ex.Message)
        Console.ReadKey()
    End Try
End Sub
End Module

当我有这个时,例如,作为我的 excel 文件:

文件名:person.xlsx 工作表名称:personfile

Name     Age     Gender
John     5       M
Jane     4       F

那么xml文件就会这样返回。

<person>
 <personfile>
  <Name>John</Name>
  <Age>5</Age>
  <Gender>M</Gender>
 </personfile>
 <personfile>
  <Name>Jane</Name>
  <Age>4</Age>
  <Gender>F</Gender>
 </personfile>
</person>

另存为person.xml

现在我的问题是……如果 excel 文件有合并单元格怎么办?如何解决错误?当excel文件合并单元格后,返回

ERROR: Index and length must refer to a location within the string
Parameter name: length

这是我应该检索的示例 excel 文件。

附:还有组合框。

【问题讨论】:

  • 你能举例说明为什么会有合并的单元格吗?我不认为对输入进行某种限制是不合理的。
  • @JBiserkov 我添加了一张我应该检索的文件的照片。有合并的单元格,更不用说组合框/复选框和日文字符
  • 必须是XML?您是否知道 xlsx 文件只是一堆压缩的.... XML 文件?将 xlsx 扩展名更改为 .zip 并双击它,您就有一堆 XML 文件。现在您已将 Excel 文件另存为 XML。我想这并不能解决你的问题。你有它应该符合的 XSD 吗?

标签: .net xml vb.net excel console-application


【解决方案1】:

这适用于我使用几种不同的合并单元格情况制作的测试表:

Private Sub Main
    Try
        Dim excel As Application = New Application
        Dim filename As String = "person"
        Dim file_extension As String
        Dim path As String = "C:\Users\"
        Dim w As Workbook
        Try
            file_extension = "xlsx"
            w = excel.Workbooks.Open(path & filename + "." & file_extension)
        Catch ex As Exception
            file_extension = "xls"
            w = excel.Workbooks.Open(path & filename + "." & file_extension)
        End Try

        For i As Integer = 1 To w.Sheets.Count
            Dim sheet As Object = w.Sheets(i)
            Dim r As Object = sheet.UsedRange

            'Changes to your original code begin here

            Dim bound0 As Integer = r.Rows.Count
            Dim bound1 As Integer = r.Columns.Count
            Dim array(bound0, bound1) As Object
            For a As Integer = 1 To bound0
                For b As Integer = 1 To bound1
                    Try
                        array(a, b) = r.Cells(a, b).Value
                    Catch
                        array(a, b) = Nothing
                    End Try
                Next
            Next

            If array IsNot Nothing Then 'I left this in, though I can't imagine how it could be needed now

                Dim settings As XmlWriterSettings = New XmlWriterSettings()
                settings.Indent = True

                Using writer As XmlWriter = XmlWriter.Create(filename + ".xml", settings)
                    writer.WriteStartDocument()
                    writer.WriteStartElement(filename)
                    For j As Integer = 2 To bound0
                        writer.WriteStartElement(sheet.Name)
                        For x As Integer = 1 To bound1
                            If array(j, x) IsNot Nothing Then
                                Dim h As Integer = x
                                Do Until array(1, h) IsNot Nothing
                                    h -= 1
                                Loop
                                writer.WriteElementString(array(1, h), array(j, x))

                                'No more changes to your code after this point

                            End If
                        Next
                        writer.WriteEndElement()
                    Next
                    writer.WriteEndElement()
                    writer.WriteEndDocument()
                End Using
            End If
        Next
        w.Close()
    Catch ex As Exception
        Console.WriteLine("MS Excel file is invalid.")
        Console.WriteLine(ex.Message)
        Console.ReadKey()
    End Try
End Sub

【讨论】:

    【解决方案2】:

    代码将表格视为没有合并单元格的二维数组。最好的方法是将其应用于符合这些标准的表格部分,例如其中没有合并单元格。

    根据文档之间结构的固定或变化程度,这可能很容易,也可能非常困难。

    假设你需要的数据总是在同一个固定位置,你可以将r变量设置为相关范围而不是整张表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-29
      • 2019-07-08
      • 2010-12-25
      • 1970-01-01
      • 2016-04-17
      • 1970-01-01
      相关资源
      最近更新 更多