读EXCEL文件时应注意的几个问题

本文介绍了一种使用Visual Basic .NET读取Excel文件的方法,包括读取指定Excel文件的第一个工作表、指定工作表的数据以及整个文件的所有数据。此外还提供了通过ODBC连接读取Excel数据和遍历Excel工作表读取数据的具体实现。
摘要由CSDN通过智能技术生成

Public Class ExcelImport

#Region "成员变量定义"

    ''' <summary>
    ''' 

    ''' </summary>
    ''' <remarks></remarks>
    Private _xlApp As Excel.Application

    ''' <summary>
    ''' 

    ''' </summary>
    ''' <remarks></remarks>
    Private _xlBooks As Excel.Workbooks

    ''' <summary>
    ''' 

    ''' </summary>
    ''' <remarks></remarks>
    Private _xlBook As Excel.Workbook

    ''' <summary>
    ''' 

    ''' </summary>
    ''' <remarks></remarks>
    Private _xlSheet As Excel.Worksheet

 

    Private eMassage As String

#End Region

 

#Region "构造函数"
    Public Sub ExcelImport()

    End Sub
#End Region

 

#Region "属性"
    Public ReadOnly Property ExMassage() As String
        Get
            Return eMassage
        End Get
    End Property
#End Region

 

#Region "方法"

    ''' <summary>
    ''' 读入指定Excel文件的第一个WorkSheet   

   ''' </summary>
    ''' <param name="sFullFilePath">读入Excel文件的路径</param>
    ''' <returns>读入EXECL文件的数据</returns>
    ''' <remarks></remarks>
    Public Function ReadExcel(ByVal sFullFilePath As String) As System.Data.DataTable
        Dim dtImport As System.Data.DataTable = Nothing
        Dim sSheetName As String
        Try

            '打开Excel进程

            _xlApp = OpenExcel(_xlApp)

            'Excel窗口是否显示
            _xlApp.Visible = False

            '打开Excel工作簿

            _xlBook = OpenBook(_xlApp, sFullFilePath)

            '取得WorkSheet

            _xlSheet = CType(_xlBook.Worksheets(1), Excel.Worksheet)

            '取得WorkSheet的名称

            sSheetName = _xlSheet.Name

            '通过ODBC连接读入数据
            dtImport = ReadExcelByOleDb(sFullFilePath, sSheetName)

        Catch ex As Exception
            Throw ex
        Finally

            '关闭工作簿
            _xlBook.Close(False, sFullFilePath, True)

            '释放Excel资源

            EndImport()
        End Try
        Return dtImport
    End Function

 

    ''' <summary>
    ''' 读入指定EXCEL文件指定的WorkSheet的数据

    ''' </summary>
    ''' <param name="sFullFilePath">读入Excel文件的路径</param>
    ''' <param name="iSheetPage">指定WorkSheet的页码</param>
    ''' <returns>读入EXECL文件的数据</returns>
    ''' <remarks></remarks>
    Public Function ReadExcel(ByVal sFullFilePath As String, ByVal iSheetPage As Integer) As System.Data.DataTable
        Dim dtImport As System.Data.DataTable = Nothing
        Dim sSheetName As String
        Try
            '打开Excel进程
            _xlApp = OpenExcel(_xlApp)

              'Excel窗口是否显示
            _xlApp.Visible = False

             '打开Excel工作簿

            _xlBook = OpenBook(_xlApp, sFullFilePath)

            '判断指定的WorkSheets是否存在
            If iSheetPage > _xlBook.Worksheets.Count And iSheetPage < 0 Then

                'msg

            End If

             '取得WorkSheet

            _xlSheet = CType(_xlBook.Worksheets(iSheetPage), Excel.Worksheet)

              '取得WorkSheet的名称

            sSheetName = _xlSheet.Name

             '通过ODBC连接读入数据
            dtImport = ReadExcelByOleDb(sFullFilePath, sSheetName)
        Catch ex As Exception
            Throw ex
        Finally

             '关闭工作簿
            _xlBook.Close(False, sFullFilePath, True)

            '释放Excel资源

            EndImport()
        End Try
        Return dtImport
    End Function

 

    ''' <summary>
    ''' 读入指定EXCEL文件的所有数据

    ''' </summary>
    ''' <param name="sFullFilePath">读入Excel文件的路径</param>
    ''' <returns>读入EXECL文件的数据</returns>
    ''' <remarks></remarks>
    Public Function ReadExcel(ByVal sFullFilePath As String, ByVal bFlag As Boolean) As System.Data.DataSet
        Dim dsImport As System.Data.DataSet = Nothing
        Dim sSheetName As String
        Dim startTime As System.DateTime
        Dim afterTime As System.DateTime
        Dim mProcessList() As System.Diagnostics.Process
        Dim fileName As String
        Dim sMassage As String
        Try

            '获取所有打开的Excel进程

            mProcessList = System.Diagnostics.Process.GetProcessesByName("EXCEL")

 

            '获取指定Excel的文件名

            fileName = GetFileName(sFullFilePath)

           

            '判断指定的Excel文件是否有同名的Excel文件打开

            For Each tmpProcess As System.Diagnostics.Process In mProcessList
                If (tmpProcess.MainWindowTitle.Contains(fileName)) Then

                    '有同名的Excel文件打开,抛出异常
                    Throw New Exception(sMassage)
                End If
            Next

 

            If (_xlApp Is Nothing) Then

                '打开Excel进程之前的时间
                startTime = System.DateTime.Now.AddSeconds(-1)

                '打开Excel进程

                _xlApp = OpenExcel(_xlApp)

                '打开Excel进程之后的时间

                afterTime = System.DateTime.Now.AddSeconds(1)
            End If

 

            'Excel窗口是否显示
            _xlApp.Visible = bFlag

               '打开Excel工作簿

            _xlBook = OpenBook(_xlApp, sFullFilePath)


            dsImport = New System.Data.DataSet

            For Each xlSheet As Excel.Worksheet In _xlBook.Worksheets
                Dim dtImport As System.Data.DataTable

                 '取得WorkSheet的名称

                sSheetName = xlSheet.Name

 

               '通过遍历EXCEL读入数据
                dtImport = ReadExcelByTraversal(xlSheet)

                dtImport.TableName = sSheetName

                dsImport.Tables.Add(dtImport)
            Next

        Catch exx As System.Runtime.InteropServices.COMException
            eMassage = exx.Message
            Throw exx
        Catch ex As Exception
            eMassage = ex.Message
            Throw ex
        Finally

             '关闭工作簿
            _xlBook.Close(False, False)

             '释放Excel资源

            EndImport()

           

            '杀死Excel进程

            KillProcess("EXCEL", startTime, afterTime)
        End Try
        Return dsImport
    End Function

 

    ''' <summary>
    '''通过ODBC连接读入数据
    ''' </summary>
    ''' <param name="sFullFilePath">读入Excel文件的路径</param>
    ''' <param name="sSheetName">WorkSheet的名称</param>
    ''' <returns>读入EXECL文件的数据</returns>
    ''' <remarks></remarks>
    Private Function ReadExcelByOleDb(ByVal sFullFilePath As String, ByVal sSheetName As String) As System.Data.DataTable
        Dim dtImport As System.Data.DataTable = Nothing
        Dim myConn As System.Data.OleDb.OleDbConnection
        Dim myAdapter As System.Data.OleDb.OleDbDataAdapter
        Dim strSql As String

        '判断EXCEL的版本
        If (_xlApp.Version = "12.0") Then
            myConn = New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source= " & sFullFilePath & ";Extended Properties = 'Excel " & _xlApp.Version & ";HDR =Yes;IMEX=1;'")
        Else
            myConn = New System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.Oledb.4.0;Data Source=" & sFullFilePath & ";Extended Properties= 'Excel 8.0;HDR=Yes;IMEX=1;'")
        End If
        strSql = "select * from " & "[" & sSheetName & "$] "

         myAdapter = New System.Data.OleDb.OleDbDataAdapter(strSql, myConn)
        dtImport = New System.Data.DataTable
        myAdapter.Fill(dtImport)
        Return dtImport
    End Function

 

     ''' <summary>
    '''通过ODBC连接读入数据
    ''' </summary>
    ''' <param name="xlSheet ">要读取得WorkSheet</param>
   ''' <returns>读入EXECL文件的数据</returns>
    ''' <remarks></remarks>
    Private Function ReadExcelByTraversal(ByVal xlSheet As Excel.Worksheet) As System.Data.DataTable
        Dim dtImport As System.Data.DataTable = Nothing
        Dim r As Excel.Range
        Dim col As Integer
        Dim row As Integer
        col = GetLastCol(xlSheet)
        row = GetLastRow(xlSheet)
        Dim o(col, row) As Object
        r = xlSheet.Range("A1", xlSheet.Cells(row, col))
        o = r.Value
        dtImport = WriteToTable(CreateTable(col), o, col, row)
        Return dtImport
    End Function

 

    Private Function CreateTable(ByVal maxCol As Integer) As System.Data.DataTable
        Dim dt As System.Data.DataTable = Nothing
        dt = New System.Data.DataTable
        For i As Integer = 0 To maxCol
            dt.Columns.Add(New DataColumn(i.ToString()))
        Next
        Return dt
    End Function

 

    Private Function WriteToTable(ByVal dt As System.Data.DataTable, ByVal pData(,) As Object, ByVal maxCol As Integer, ByVal maxRow As Integer) As System.Data.DataTable
        Dim obj() As Object
        Dim oneLineIsNotNothing As Boolean = False
        For i As Integer = 1 To maxRow - 1
            obj = New Object(maxCol) {}
            For j As Integer = 0 To maxCol - 1
                If (pData(i, j + 1) IsNot Nothing AndAlso pData(i, j + 1).ToString() <> "") Then
                    oneLineIsNotNothing = True
                End If
                obj(j) = pData(i, j + 1)
            Next
            If (oneLineIsNotNothing) Then
                dt.Rows.Add(obj)
            End If
            oneLineIsNotNothing = False
        Next
        Return dt
    End Function

 

   '获取Excel的最大活动的列

    Private Function GetLastCol(ByVal xlSheet As Excel.Worksheet) As Integer
               Return xlSheet.UsedRange.Columns.Count
    End Function

 

    '获取Excel的最大活动的行

    Private Function GetLastRow(ByVal xlSheet As Excel.Worksheet) As Integer
        Return xlSheet.UsedRange.Rows.Count
    End Function

 

    ''' <summary>
    '''    打开Excel工作簿  

    ''' </summary>
    ''' <param name="xlApp">应用程序</param>
    ''' <param name="sFullFilePath">Excel文件的路径</param>
    ''' <returns>ワークブック</returns>
    ''' <remarks></remarks>
    Private Function OpenBook(ByVal xlApp As Excel.Application, ByVal sFullFilePath As String) As Excel.Workbook

        Return xlApp.Workbooks.Open(sFullFilePath _
                                    , System.Reflection.Missing.Value _
                                    , System.Reflection.Missing.Value _
                                    , System.Reflection.Missing.Value _
                                    , System.Reflection.Missing.Value _
                                    , System.Reflection.Missing.Value _
                                    , System.Reflection.Missing.Value _
                                    , System.Reflection.Missing.Value _
                                    , System.Reflection.Missing.Value _
                                    , System.Reflection.Missing.Value _
                                    , System.Reflection.Missing.Value _
                                    , System.Reflection.Missing.Value _
                                    , System.Reflection.Missing.Value)
    End Function

 

    ''' <summary>
    ''' 打开Excel的进程
    ''' </summary>
    ''' <param name="xlApp">应用程序</param>
    ''' <returns>Excel的进程</returns>
    ''' <remarks></remarks>
    Private Function OpenExcel(ByVal xlApp As Excel.Application) As Excel.Application
        Dim sStr As String = Nothing
        Dim sVersion As String
        Dim sMessage As String = "没有发现Excel程序。/n请确认以下版本Microsoft Excel是否安装。/n・Excel97/n・Excel2000/n・ExcelXP/n・Excel2003/n・Excel2007"
        Try
            xlApp = New Excel.Application()
            xlApp.DisplayAlerts = False
            sVersion = xlApp.Version
        Catch ex As System.Runtime.InteropServices.COMException
            Throw New Exception(sMessage)
        End Try
        Dim strArray As String()
        Dim ch As Char = CChar(".")
        strArray = sVersion.Split(ch)
        If (strArray.Length > 0) Then
            sVersion = strArray(0)
        End If
        sStr = sVersion
        If ((sStr = Nothing) Or ((((sStr <> "8") And (sStr <> "9")) And ((sStr <> "10") And (sStr <> "11"))) And (sStr <> "12"))) Then
            Throw New Exception(sMessage)
        End If
        Return xlApp
    End Function


    ''' <summary>
    ''' 释放使用中的资源

    ''' </summary>
    ''' <remarks></remarks>
    Public Sub EndImport()
        If (Not (_xlApp Is Nothing)) Then
            _xlApp.Quit()
        End If
        If (Not (_xlBooks Is Nothing)) Then
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(_xlBooks)
        End If
        If (Not (_xlBook Is Nothing)) Then
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(_xlBook)
        End If
        If (Not (_xlSheet Is Nothing)) Then
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(_xlSheet)
        End If
        Me._xlBooks = Nothing
        Me._xlBook = Nothing
        Me._xlSheet = Nothing
        If (Not (Me._xlApp Is Nothing)) Then
            Dim iGen As Integer
            iGen = System.GC.GetGeneration(_xlApp)
            Me._xlApp = Nothing
            System.GC.Collect(iGen)
        End If
    End Sub

 

 '杀死Excel进程
    Private Sub KillProcess(ByVal processName As String, ByVal beforeStartTime As System.DateTime, ByVal afterStartTime As System.DateTime)
        Dim mProcessList() As System.Diagnostics.Process
        Dim mProcessStartTime As System.DateTime
        mProcessList = System.Diagnostics.Process.GetProcessesByName(processName)
        For Each tmpProcess As System.Diagnostics.Process In mProcessList
            mProcessStartTime = tmpProcess.StartTime
            If (mProcessStartTime.CompareTo(beforeStartTime) > 0 And mProcessStartTime.CompareTo(afterStartTime) < 0) Then
                tmpProcess.Kill()
                Exit Sub
            End If
        Next
    End Sub


    ''' <summary>
    ''' 从文件的全路径中获取文件名

    ''' </summary>
    ''' <param name="sFullFilePath">ファイルのフルパス</param>
    ''' <returns>ファイル名</returns>
    ''' <remarks></remarks>
    Function GetFileName(ByVal sFullFilePath As String) As String
        Dim I As Integer
        Dim strFileName As String
        Dim str As String()
        If (Not (System.IO.File.Exists(sFullFilePath))) Then
            Return Nothing
        End If
        For I = Len(sFullFilePath) To 1 Step -1
            If CBool(InStr("/", Mid$(sFullFilePath, I, 1))) Then Exit For
        Next
        strFileName = Mid$(sFullFilePath, I + 1, Len(sFullFilePath) - I)
        str = strFileName.Split(CChar("."))
        strFileName = str(0)
        Return strFileName
    End Function

#End Region
End Class

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值