天天看點

VB.NET Excel導入

最近上班發現一定要注意兩點:

1.前台的字段類型一定要與資料庫保持一緻!!!

2.一定要做非空判斷!!!

下面進入正題,最近兩天在做excel表格批量導入,從前台程式直接打開EXCEL,批量導入到資料庫中

思路是:

1.先把EXCEL表格轉換成Datatable,

2.然後datatable轉成list,

3.把list儲存到資料庫中

1.首先在NPOI類中寫四個方法,導入的,兩個導入進入轉換成datatable,(一個xls,一個xlsx),兩個讀取格式的(*就是第一步,轉換成datatable)

Public Shared Function ExcelToTableForXLS(ByVal filePath As String) As DataTable
        Dim dt As DataTable = New DataTable
        Dim fs As FileStream = New FileStream(filePath, FileMode.Open, FileAccess.Read)
        Dim hssfworkbook As HSSFWorkbook = New HSSFWorkbook(fs)
        Dim sheet As ISheet = hssfworkbook.GetSheetAt()
        '表頭
        Dim header As IRow = sheet.GetRow(sheet.FirstRowNum)
        Dim columns As List(Of Integer) = New List(Of Integer)
        Dim i As Integer = 
        Do While (i < header.LastCellNum)
            Dim obj As Object = GetValueTypeForXLS(CType(header.GetCell(i), HSSFCell))
            If ((obj Is Nothing) OrElse (obj.ToString = String.Empty)) Then
                dt.Columns.Add(New DataColumn(("Columns" + i.ToString)))
                'continue;
            Else
                dt.Columns.Add(New DataColumn(obj.ToString))
            End If

            columns.Add(i)
            i = (i + )
        Loop

        '資料
        Dim m As Integer = (sheet.FirstRowNum + )
        Do While (m <= sheet.LastRowNum)
            Dim dr As DataRow = dt.NewRow
            Dim hasValue As Boolean = False
            For Each j As Integer In columns
                dr(j) = GetValueTypeForXLS(CType(sheet.GetRow(m).GetCell(j), HSSFCell))
                If ((Not (dr(j)) Is Nothing) _
                            AndAlso (dr(j).ToString <> String.Empty)) Then
                    hasValue = True
                End If

            Next
            If hasValue Then
                dt.Rows.Add(dr)
            End If

            m = (m + )
        Loop

        Return dt
    End Function


    Private Shared Function GetValueTypeForXLS(ByVal cell As HSSFCell) As Object
        If (cell Is Nothing) Then
            Return Nothing
        End If

        Select Case (cell.CellType)
            Case CellType.BLANK
                'BLANK:
                Return Nothing
            Case CellType.BOOLEAN
                'BOOLEAN:
                Return cell.BooleanCellValue
            Case CellType.NUMERIC
                'NUMERIC:
                Return cell.NumericCellValue
            Case CellType.STRING
                'STRING:
                Return cell.StringCellValue
            Case CellType.ERROR
                'ERROR:
                Return cell.ErrorCellValue
            Case CellType.FORMULA
                'FORMULA:
                Select Case (cell.CellType)
                    Case CellType.BLANK
                        Return DBNull.Value
                    Case CellType.BOOLEAN
                        Return cell.BooleanCellValue
                    Case CellType.NUMERIC
                        Return cell.NumericCellValue
                    Case CellType.STRING
                        Return cell.StringCellValue
                    Case CellType.ERROR
                        Return cell.ErrorCellValue
                    Case Else
                        Return cell.CellType
                End Select

            Case Else
                Return ("=" + cell.CellFormula)
        End Select

    End Function


    Private Shared Function GetValueTypeForXLSX(ByVal cell As XSSFCell) As Object
        If (cell Is Nothing) Then
            Return DBNull.Value
        End If

        Select Case (cell.CellType)
            Case CellType.BLANK
                'BLANK:   
                Return DBNull.Value
            Case CellType.BOOLEAN
                'BOOLEAN:   
                Return cell.BooleanCellValue
            Case CellType.NUMERIC
                'NUMERIC:   
                Return cell.NumericCellValue
            Case CellType.STRING
                'STRING:   
                Return cell.StringCellValue
            Case CellType.ERROR
                'ERROR:   
                Return cell.ErrorCellValue
            Case CellType.FORMULA
                'FORMULA: 
                Select Case (cell.CachedFormulaResultType)
                    Case CellType.BLANK
                        'BLANK:
                        Return DBNull.Value
                    Case CellType.BOOLEAN
                        'BOOLEAN:
                        Return cell.BooleanCellValue
                    Case CellType.NUMERIC
                        'NUMERIC:
                        Return cell.NumericCellValue
                    Case CellType.STRING
                        'STRING:
                        Return cell.StringCellValue
                    Case CellType.ERROR
                        'ERROR:
                        Return cell.ErrorCellValue
                    Case Else
                        Return cell.CellType
                End Select

            Case Else
                Return ("=" + cell.CellFormula)
        End Select

    End Function


    Public Shared Function ExcelToTableForXLSX(ByVal filePath As String) As DataTable
        Dim dt As DataTable = New DataTable
        Dim fs As FileStream = New FileStream(filePath, FileMode.Open, FileAccess.Read)
        Dim xssfworkbook As XSSFWorkbook = New XSSFWorkbook(fs)
        Dim sheet As ISheet = xssfworkbook.GetSheetAt()
        '表頭   
        Dim header As IRow = sheet.GetRow(sheet.FirstRowNum)
        Dim columns As List(Of Integer) = New List(Of Integer)
        Dim i As Integer = 
        Do While (i < header.LastCellNum)
            Dim obj As Object = GetValueTypeForXLSX(CType(header.GetCell(i), XSSFCell))
            If ((obj Is Nothing) _
                        OrElse (obj.ToString = String.Empty)) Then
                dt.Columns.Add(New DataColumn(("Columns" + i.ToString)))
                'continue;   
            Else
                dt.Columns.Add(New DataColumn(obj.ToString))
            End If

            columns.Add(i)
            i = (i + )
        Loop

        '資料
        Dim m As Integer = (sheet.FirstRowNum + )
        Do While (m <= sheet.LastRowNum)
            Dim dr As DataRow = dt.NewRow
            Dim hasValue As Boolean = False
            For Each j As Integer In columns
                dr(j) = GetValueTypeForXLSX(CType(sheet.GetRow(m).GetCell(j), XSSFCell))
                If ((Not (dr(j)) Is Nothing) _
                            AndAlso (dr(j).ToString <> String.Empty)) Then
                    hasValue = True
                End If

            Next
            If hasValue Then
                dt.Rows.Add(dr)
            End If

            m = (m + )
        Loop

        Return dt
    End Function
           

其中,引用了四個包,

VB.NET Excel導入

然後在這個批量導入按鈕内寫入的内容:(*就是第二步,datatable轉換成List)

Dim OpenFileDialog1 As New OpenFileDialog
        OpenFileDialog1.Filter = "Excel files(*.xls)|*.xls"
        OpenFileDialog1.ShowDialog()
        Dim strPath As String = OpenFileDialog1.FileName.ToString
        If OpenFileDialog1.FileName = "" Then
            MessageBox.Show("請選擇檔案")
            Exit Sub
        End If


        Dim dtin = NPOIHelper.ExcelToTableForXLS(strPath)
        Dim bllo As New BllM_MaterialManagementT
        ' Dim oo As New M_MaterialManagementT
        Dim listMm As New List(Of M_MaterialManagementT)

        For Each uu In dtin.Rows
            '共21個字段,除去Id自增列為20,(除去NUMBER,date,IsState)-17
            Dim oo As New M_MaterialManagementT
            'MaterialNumber
            'oo.MaterialNumber = uu("MaterialNumber")
            'MaterialName
            If Not uu("MaterialName") Is DBNull.Value Then
                oo.MaterialName = uu("MaterialName")
            End If

            'MerchantID
            If Not uu("MerchantID") Is DBNull.Value Then
                oo.MerchantID = uu("MerchantID")
            End If

            'ClassA
            If Not uu("ClassA") Is DBNull.Value Then
                oo.ClassA = uu("ClassA")
            End If


            listMm.Add(oo)
            'Dim m = bllo.Insert(oo)
            'If m > 0 Then

            'Else
            '    CommonMsg.ShowMsg(Me.Text, Constant.ENU_MSGID.MSGID67)
            '    Return
            'End If

        Next

        Dim y = bllo.Insertlist(listMm)
        If y >  Then
            CommonMsg.ShowMsg(Me.Text, Constant.ENU_MSGID.MSGID62)
        Else
            CommonMsg.ShowMsg(Me.Text, Constant.ENU_MSGID.MSGID67)
        End If


    End Sub
           

其中注釋掉的代碼是之前寫的,作為datatable接收,直接用datatable插入,沒有問題,後來想寫的規範點,轉一下list

3.下面是bll層和dal層,作為List實作插入資料庫的方法:

bll層:

#Region " InsertlistEXCEL "

    '插入資料
    Public Function Insertlist(ByVal listPp As List(Of M_MaterialManagementT)) As Integer


        Dim objDalM_MaterialManagementT As New DalM_MaterialManagementT
        Dim ObjDBConn As New DbHelper
        Dim strSql As String = String.Empty
        Dim listSql As New List(Of String)
        strErrorName = "BllM_MaterialManagement.Insertlist"
        Dim i As Integer = 
        Try

            listSql = objDalM_MaterialManagementT.Savelist(listPp)
            For Each uu In listSql
                Dim sql As String = String.Empty
                sql = uu
                intRows = ObjDBConn.ExcuteScalar(sql)
            Next


            ObjDBConn.Dispose()

            Return intRows

        Catch ex As Exception
            ExHelper.ProcessDBHelper(ObjDBConn)
            Throw New Exception(strErrorName, ex)
        End Try

    End Function

#End Region
           

dal層1:

Public Shared ReadOnly MNumber = "SELECT isnull(RIGHT('000000' + convert(nvarchar(6),cast (MAX(Id) as int) + 1),6),'000001') FROM M_MaterialManagement"
    Public Function Savelist(ByVal listPp As List(Of M_MaterialManagementT)) As List(Of String)
        Dim listSql As New List(Of String)

        For Each pp In listPp
            Dim sql As String = String.Empty
            pp.MaterialNumber = MNumber
            sql = Insertexcel(pp)
            listSql.Add(sql.ToString)
        Next

        Return listSql
    End Function
           

dal層2:

#Region " Insert "

    '資料插入操作
    Public Function Insertexcel(ByVal clsM_MaterialManagementT As M_MaterialManagementT) As String

        Dim strSql As New StringBuilder(System.String.Empty)    'Sql文

        Try

            strSql.Append(" INSERT INTO M_MaterialManagement")         '原材料資訊管理表

            strSql.Append(" (MaterialNumber")         '産品編号
            strSql.Append(" ,MaterialName")           '産品名稱
            strSql.Append(" ,MerchantID")         '商戸編号
               strSql.Append(")")

            strSql.Append(" VALUES ")

            '産品編号
            strSql.Append(" ((" + clsM_MaterialManagementT.MaterialNumber + ")")

            '産品名稱
            strSql.Append(" ,'" & Utility.ChangeQuotation(clsM_MaterialManagementT.MaterialName) & "'")

            '商戸編号
            If clsM_MaterialManagementT.MerchantID = "" Then
                strSql.Append(" ,NULL ")
            Else
                strSql.Append(" ,'" & Utility.ChangeQuotation(clsM_MaterialManagementT.MerchantID) & "'")
            End If

            strSql.Append(") select @@IDENTITY")
            Return strSql.ToString

        Catch ex As Exception
            Return String.Empty
            MessageBox.Show(ex.ToString)
        End Try

    End Function
           

在UI層循環那裡,循環前先定義個泛型集合,model的list,

循環excel轉換成的datatable,将他每一列一一指派給list,每次循環結束後listadd()

循環全部結束,得到一個List,把這個List帶到BLL層裡,再從BLL層進入dal層,然後把這個List循環,每行都走插入語句。

繼續閱讀