WebApp匯入CSV資料

1、情景
點擊“匯入”按鈕,打開匯入對話框(圖一)以匯入Excel或CSV文件。匯入的過程中,會check資料是否合法有效。check每一筆并記錄error信息,如果一筆或多餘一筆則show error。
否則show在Datagrid上(圖二)。
然後,按下“保存”按鈕,Datagrid上的資料寫入DB。


2、分析
CSV文件上upload到server上,并將CSV文件轉為dataset,dataset轉為xml。然後xml的值為對話框的值返回,賽道隱藏欄位。
再將隱藏欄位的值轉為xml,轉為Dataset。check每一行,有error寫入DB,跳轉到error頁面,從DB中抓出error以顯示。


3、實現
上傳CSV對話框部分
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    End Sub

    Public Function GetImportDataSetFromCSV(ByVal sCSVFile As String) As String
        GetImportDataSetFromCSV = ""
        Try
            Dim dtImport As New DataTable
            Dim sContentb As Byte()
            IO.ReadBinaryFile(sContentb, sCSVFile)

            Dim sContent As String
            Dim splitChar As String = ","
            If sContentb(0) = 255 And sContentb(1) = 254 Then
                sContent = New System.Text.UnicodeEncoding().GetString(sContentb)
                sContent = sContent.Substring(1, sContent.Length - 1)
                splitChar = vbTab
            Else
                sContent = New String(System.Text.Encoding.Default.GetString(sContentb))
                splitChar = ","
            End If

            Dim aryLine() As String = sContent.Replace(vbCrLf, Chr(3)).Split(Chr(3))
            Dim iLine As Integer
            Dim iCol1 As Integer
            Dim tstr As String

            For iLine = 0 To aryLine.Length - 1
                If aryLine(iLine) <> "" Then
                    Dim aryCol() As String = aryLine(iLine).Replace(""" & splitChar & """, Chr(2) + Chr(3) + Chr(2)).Replace(""" & splitChar, Chr(2) + Chr(3)).Replace( splitChar & """, Chr(3) + Chr(2)).Split(Chr(3))

                    If iLine = 0 Then
                        tstr = aryCol(0).Replace(Chr(2), "")
                        For iCol1 = 0 To tstr.Split(splitChar).Length - 1
                            dtImport.Columns.Add(tstr.Split(splitChar).GetValue(iCol1))
                        Next
                    Else
                        Dim iCol As Integer
                        For iCol = 0 To aryCol.Length - 1
                            If aryCol(iCol).IndexOf(Chr(2)) < 0 Then aryCol(iCol) = aryCol(iCol).Replace(splitChar, Chr(3))
                            aryCol(iCol) = aryCol(iCol).Replace("""""", """")
                        Next

                        Dim sNewLine As String = ""
                        For iCol = 0 To aryCol.Length - 1
                            sNewLine += IIf(sNewLine = "", aryCol(iCol), Chr(3) + aryCol(iCol))
                        Next

                        aryCol = sNewLine.Split(Chr(3))

                        Dim dr As DataRow = dtImport.NewRow()

                        For iCol = 0 To aryCol.Length - 1
                            dr.Item(iCol) = aryCol(iCol).Replace(Chr(2), "")
                        Next
                        dtImport.Rows.Add(dr)
                    End If
                End If
            Next

            Dim ds As New DataSet
            ds.Tables.Add(dtImport)
            Return ds.GetXml()
        Catch ex As Exception
            Dim s As String = ex.Message.ToString()
        End Try
    End Function

    Protected Sub btnOK_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOK.Click
        If Not (UploadFile.PostedFile Is Nothing) Then
            Dim strBasePath As String = Server.MapPath("bin")
            Dim strFileName As String = Path.GetFileName(UploadFile.PostedFile.FileName)
            Dim strFileSize As String = UploadFile.PostedFile.ContentLength

            If UCase(Right(strFileName, 3)) <> "CSV" Then
                Dim sScript As String = ""
                sScript += "<script language=javascript>"
                sScript += "alert('Import file format only support Excel .csv file !')"
                sScript += "</script>"
                Page.RegisterStartupScript("OkClick", sScript)
                Exit Sub
            End If

            Try
                Dim sKeyId As String = Guid.NewGuid.ToString()
                UploadFile.PostedFile.SaveAs(strBasePath & "\" & sKeyId & ".csv")

                Dim sData As String = GetImportDataSetFromCSV(strBasePath & "\" & sKeyId & ".csv")

                Dim sScript As String = ""
                sScript += "<script language=javascript>"
                sScript += "window.returnValue = '" + DESEncrypt.Encrypt(Server.UrlEncode(sData)) & "';"
                sScript += "window.close();"
                sScript += "</script>"
                Page.RegisterStartupScript("OkClick", sScript)

                File.Delete(strBasePath & "\" & sKeyId & ".csv")
            Catch ex As Exception
            End Try
        End If
    End Sub

Check CSV內容部分
    Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click

    End Sub

    Private Sub ShowImportData()
        Dim myCmd As New SqlClient.SqlCommand()
        Dim Param As SqlClient.SqlParameter

        Dim sImportCSVData As String
        Dim ds As New DataSet
        Dim sr As System.IO.StringReader
        Dim bError As Boolean = False

        ' Xml to dataset
        sImportCSVData = Server.UrlDecode(DESEncrypt.Decrypt(ImportExcel.Text))
        sr = New System.IO.StringReader(sImportCSVData)
        ds.ReadXml(sr)

        ' Check Row
        Dim dv As New DataView(ds.Tables(0))
        Dim iRow As Integer
        Dim iCol1 As Integer

        For iRow = 0 To ds.Tables(0).Rows.Count - 1
            Dim sError As String = ""
            Dim tstr As String

            With ds.Tables(0).Rows(iRow)
                .Item("NO") = iRow + 1

                tstr = CheckDataInCS() 'check func.

                If tstr = "" Then
                Else
                    sError += tstr & "<br>"
                End If

                If sError.Trim() <> String.Empty Then
                    .Item("ERROR") = sError
                End If

                If sError <> "" Then bError = True
            End With
        Next

        ' if error, then insert it into table,and jump error message,show error.
        If bError Then
            ImportExcel.text = ""

            Dim sGuid As String = Guid.NewGuid().ToString()

            myCmd.CommandText = "INSERT INTO [TMP_EXCELIMPORT] (KeyID, FIELDVALUE) VALUES (@KeyID, @FIELDVALUE)"
            Param = New SqlClient.SqlParameter("@KeyID", sGuid)
            myCmd.Parameters.Add(Param)

            Param = New SqlClient.SqlParameter("@FIELDVALUE", System.Data.SqlDbType.NText)
            Param.Value = ds.GetXml()
            myCmd.Parameters.Add(Param)
            myCmd.ExecuteNonQuery()

            Dim sErrorScript As String = "<script language=javascript>"
            sErrorScript += "alert('Import source data occur error or duplicate, Press OK to view output file !');"
            sErrorScript += "var OpenUrl = escape('ImportError.aspx');"
            sErrorScript += "var OpenParam = 'KeyId=' + escape('" + sGuid + "');"
            sErrorScript += "var url = OpenUrl + '?' + OpenParam;"
            sErrorScript += "ret = window.open(url);"
            sErrorScript += "</script>"
            Page.RegisterStartupScript("GridNoData", sErrorScript)

            Exit Sub
        End If
    End Sub

posted @ 2010-10-26 14:30  yellowwood  阅读(256)  评论(0编辑  收藏  举报
Never Give UP