使用OleDb导入时正在修剪CSV字符串

时间:2018-01-25 11:47:17

标签: vb.net csv oledb trim

我正在使用oledb机制阅读csv文件。我的主要问题是在读取时csv中的字符串值正在被修剪(两者:在开始和结束时都有空格)。我在csv文件中有一些特定的数据,在某些情况下需要有这样的空格 - 这就是我在处理后无法处理的原因。它必须通过转换来完成。

不幸的是,由于我们的复杂机制基于这些技术,因此必须使用oledb和vb.net。

是否有可能找到oledb不会修剪我的字符串的黑客或解决方法?

以下是我的代码,实际结果和预期:

csv文件:

Column1|Column2|Column3|Column4
Text1 | Text2| Text3 |Text4

SCHEMA.INI

[test.csv]
Format=Delimited(|)
Col1=Column1 Text
Col2=Column2 Text
Col3=Column3 Text
Col4=Column4 Text

代码

Private conn As New OleDbConnection
Private cmd As New OleDbCommand
Private myAccessDataReader As OleDb.OleDbDataReader = Nothing
Sub Main()

    Try
        Dim dirInfo As String = "C:\csv"

        If conn.State = ConnectionState.Open Then
            conn.Close()
        End If

        conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & dirInfo & ";Extended Properties=""Text;HDR=Yes;"";"
        conn.Open()

        cmd = New OleDbCommand("SELECT * From [test.csv]", conn)

        myAccessDataReader = cmd.ExecuteReader()
        If myAccessDataReader.HasRows Then
            myAccessDataReader.Read()
        End If

        Console.WriteLine("|" + myAccessDataReader.Item("Column1") + "|")
        Console.WriteLine("|" + myAccessDataReader.Item("Column2") + "|")
        Console.WriteLine("|" + myAccessDataReader.Item("Column3") + "|")
        Console.WriteLine("|" + myAccessDataReader.Item("Column4") + "|")
        Console.ReadKey()

    Catch ex As Exception
        Throw New Exception(ex.Message)
    End Try


End Sub

实际结果:

|Text1|
|Text2|
|Text3|
|Text4|

预期结果:

|Text1 |
| Text2|
| Text3 |
|Text4|

聚苯乙烯。我尝试过schema.ini中的不同设置:encoding,MaxScanRows,固定宽度,但没有任何帮助。

2 个答案:

答案 0 :(得分:0)

我想在处理数据库时有一个跟踪空格的一般问题:一些char数据类型使用空格来填充其余的字符。对于MSSql,有一个选项ANSI PADDING,你可以打开/关闭,但我没有看到为我们用于CSV文件的Microsoft JET引擎设置的方法;我们支持oledb和odbc,这个问题都存在。

所以,答案是你不能。无论是否为列定义text / char / memo数据类型(例如,使用schema.ini)或将字符串括在双引号中,当您从CSV数据源导入数据时,将始终删除尾随空格。例如,您可以在空格之后放置一些特殊字符(非空格),例如制表符。

microsoft website

答案 1 :(得分:-1)

试试这个.....但由于我没有做任何错误处理,因此无法保证......

Function ReadCSVToTable(ByVal Schema As String) As DataTable
    Dim file As New StreamReader("C:\dump\" & Schema)
    Dim CSVName As String = file.ReadLine()
    CSVName = Strings.Mid(CSVName, 2, CSVName.Length - 2)
    Dim Delimiter As String = file.ReadLine
    Delimiter = Strings.Mid(Delimiter, Strings.InStr(Delimiter, "(") + 1, Delimiter.Length - Strings.InStr(Delimiter, ")") + 1)
    Dim Buffer As String = ""
    Dim xtable As New DataTable
    xtable.TableName = CSVName
    'create table
    Do
        Buffer = file.ReadLine
        Dim xCol As New DataColumn
        With xCol
            .ColumnName = Buffer.Split("=")(0)
            .Caption = Buffer.Split("=")(1).Split(" ")(0)
            Select Case Buffer.Split("=")(1).Split(" ")(1).ToLower
                Case "text"
                    .DataType = GetType(String)
                Case "integer"
                    .DataType = GetType(Integer)
                Case "decimal"
                    .DataType = GetType(Decimal)
                Case "boolean"
                    .DataType = GetType(Boolean)
                Case Else
                    .DataType = GetType(String)
            End Select
        End With
        xtable.Columns.Add(xCol)
    Loop Until file.EndOfStream = True
    file.Close()
    file.Dispose()


    'Fill the table
    file = New StreamReader("C:\dump\" & CSVName)
    'skip header
    Buffer = file.ReadLine
    Do
        Buffer = file.ReadLine
        Dim xCol(xtable.Columns.Count - 1)
        Dim xCount As Integer = 0
        For Each tCol As DataColumn In xtable.Columns
            Select Case tCol.DataType
                Case GetType(String)
                    xCol(xCount) = Convert.ToString(Buffer.Split(New String() {Delimiter}, StringSplitOptions.None)(xCount))
                Case GetType(Integer)
                    xCol(xCount) = Convert.ToInt64(Buffer.Split(New String() {Delimiter}, StringSplitOptions.None)(xCount))
                Case GetType(Decimal)
                    xCol(xCount) = Convert.ToDecimal(Buffer.Split(New String() {Delimiter}, StringSplitOptions.None)(xCount))
                Case GetType(Boolean)
                    xCol(xCount) = Convert.ToBoolean(Buffer.Split(New String() {Delimiter}, StringSplitOptions.None)(xCount))
                Case Else
                    xCol(xCount) = Convert.ToString(Buffer.Split(New String() {Delimiter}, StringSplitOptions.None)(xCount))
            End Select
            xCount = xCount + 1
        Next
        xtable.Rows.Add(xCol)
    Loop Until file.EndOfStream = True
    file.Close()
    file.Dispose()
    Return xtable
End Function
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim CSVTable As DataTable = ReadCSVToTable("schema.ini")
End Sub