ExcelReader

Imports System.Data
Imports System.Data.OleDb
Imports System.IO

''' <summary>
''' 读取Excel
''' </summary>
Public Class ExcelReader
    Implements IDisposable
    '连接字符串说明
    'HDR=Yes:将第一行作为DataTable的列名,根据该列的数据判断该列的数据类型
    'HDR=No:将所有行都作为数据,所有的数据类型都是string,空值为空字符串""
    'IMEX=0:汇出模式,这个模式开启的Excel档案只能用来做“写入”用途。
    'IMEX=1:汇入模式,这个模式开启的Excel档案只能用来做“读取”用途。
    'IMEX=2:连結模式,这个模式开启的Excel档案可同时支持“读取”与“写入”用途。
    Private Const connectionString As String = "Provider={0};Data Source={1};Extended Properties='{2};HDR={3};IMEX=1'"
    Private con As OleDbConnection

    Sub New(ByVal filename As String)
        Me.New(filename, True)
    End Sub

    Sub New(ByVal filename As String, ByVal hasHead As Boolean)
        ChangeExcel(filename, hasHead)
    End Sub

    Protected Sub ChangeExcel(ByVal filename As String, ByVal hasHead As Boolean)
        con = Nothing
        If ValidatePath(filename) Then
            con = New OleDbConnection
            con.ConnectionString = GetConnectionStr(filename, hasHead)
        End If
    End Sub

    Public Function ReadDataSet() As DataSet
        If con Is Nothing Then Return Nothing
        Dim sheetNames As List(Of String) = GetSheetNames()
        sheetNames.RemoveAll(
            Function(n)
                Return Not n.EndsWith("$")
            End Function)
        Return ReadDataSet(sheetNames)
    End Function

    Public Function ReadDataSet(ByVal sheetNames As IEnumerable(Of String)) As DataSet
        If con Is Nothing Then Return Nothing
        Dim ds As New DataSet
        For Each name In sheetNames
            Dim dt As DataTable = ReadDataTable(name)
            Try
                ds.Tables.Add(dt)
            Catch ex As Exception
                MsgBox(ex.Message)
            End Try
        Next
        Return ds
    End Function

    Public Function ReadDataTable(ByVal sheetName As String) As DataTable
        If con Is Nothing Then Return Nothing
        '过滤隐藏表,Oledb读取表会在表后面加上$符号,对于一些有公式的sheet,OleDb会创建一个隐藏表,但这些表没有加上$符号
        If sheetName.EndsWith("$") Then
            sheetName = sheetName.Substring(0, sheetName.Length - 1)
        End If
        Dim dt As New DataTable(sheetName)
        Dim sqlText As String = String.Format("select * from [{0}$]", sheetName)
        Using da As New OleDbDataAdapter(sqlText, con)
            Try
                da.Fill(dt)
            Catch ex As Exception
                Return Nothing
            End Try
        End Using
        Return dt
    End Function

    ''' <summary>
    ''' 获取Sheet名称列表
    ''' </summary>
    Public Function GetSheetNames() As IEnumerable(Of String)
        If con Is Nothing Then Return Nothing
        con.Open()
        Dim dt As DataTable = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, Nothing)
        Dim list As New List(Of String)
        For Each row As DataRow In dt.Rows
            list.Add(row("TABLE_NAME").ToString)
            'System.Threading.Interlocked.Increment(i)
        Next
        con.Close()
        Return list
    End Function

    ''' <summary>
    ''' 验证文件Path
    ''' </summary>
    Protected Shared Function ValidatePath(ByVal excelPath As String) As Boolean
        If File.Exists(excelPath) Then
            Dim suffix As String = Path.GetExtension(excelPath).ToLower
            If suffix.Equals(".xls") OrElse suffix.Equals(".xlsx") Then
                Return True
            End If
        End If
        Return False
    End Function

    ''' <summary>
    ''' 构造连接字符串
    ''' </summary>
    Protected Shared Function GetConnectionStr(ByVal excelPath As String, ByVal hasHead As Boolean) As String
        Dim constr As String = String.Empty
        If File.Exists(excelPath) Then
            Dim suffix As String = Path.GetExtension(excelPath).ToLower
            Dim excelVersion As String
            Dim provider As String
            If suffix.Equals(".xlsx") Then
                provider = "Microsoft.Ace.OleDb.12.0"
                excelVersion = "Excel 12.0"
            ElseIf suffix.Equals(".xls") Then
                provider = "Microsoft.Jet.OLEDB.4.0"
                excelVersion = "Excel 8.0"
            Else
                Return String.Empty
            End If
            Return String.Format(connectionString, provider, excelPath, excelVersion, If(hasHead, "yes", "no"))
        End If
        Return String.Empty
    End Function

#Region "IDisposable Support"
    Private disposedValue As Boolean ' 检测冗余的调用

    ' IDisposable
    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
        If Not Me.disposedValue Then
            If disposing Then
                ' TODO: 释放托管状态(托管对象)。
            End If
            con.Dispose()
            ' TODO: 释放非托管资源(非托管对象)并重写下面的 Finalize()。
            ' TODO: 将大型字段设置为 null。
        End If
        Me.disposedValue = True
    End Sub

    ' TODO: 仅当上面的 Dispose(ByVal disposing As Boolean)具有释放非托管资源的代码时重写 Finalize()。
    'Protected Overrides Sub Finalize()
    '    ' 不要更改此代码。请将清理代码放入上面的 Dispose(ByVal disposing As Boolean)中。
    '    Dispose(False)
    '    MyBase.Finalize()
    'End Sub

    ' Visual Basic 添加此代码是为了正确实现可处置模式。
    Public Sub Dispose() Implements IDisposable.Dispose
        ' 不要更改此代码。请将清理代码放入上面的 Dispose(ByVal disposing As Boolean)中。
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
#End Region

End Class

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值