我试图将人员本地计算机上的CSV文件上传到我的程序中,但我遇到了一些麻烦。我有一列是数字和文本的混合,例如F-23,Pool等。但是,当我上传文件时,它会将该列专门视为十进制列。无论如何我可以将所有列值设置为字符串类型以避免这种情况吗?我现在正在使用Oledb将csv上传到数据表中。
将csv上传到数据表中的代码如下。
Dim conn As OleDbConnection = New
OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" &
Path.GetDirectoryName(fullDir) & ";Extended
Properties=""Text;HDR=Yes;FMT=Delimited(,);IMEX=1"";")
conn.Open()
Dim adp As New OleDbDataAdapter("SELECT * FROM [" & fileName & "]", conn)
adp.Fill(dt)
conn.Close()
答案 0 :(得分:2)
如果您知道列是:
,那么您可以处理这种情况的好方法让我们在这里使用人事档案的小例子。
1 /使用各自的列
创建表CREATE TABLE My_Personnel(
ID INT NOT NULL,
NAME VARCHAR (50) NOT NULL,
AGE INT NOT NULL,
ADDRESS VARCHAR (1000) ,
PRIMARY KEY (ID)
);
然后你会创建一个 Class 来存储这样的数据:
Public Class Person
Public Property ID As Integer
Public Property Name As String
Public Property Age As Integer
Public Property Address As String
End Class
然后您将创建功能以使用TextFieldParser
提取数据:
Imports Microsoft.VisualBasic.FileIO.TextFieldParser
ExtractData 功能:
Public Function ExtractData(ByVal csvData As String) As List(Of Person)
Dim result As New List(Of Person)
Dim afile As FileIO.TextFieldParser = New FileIO.TextFieldParser(csvData)
Dim CurrentRecord As String() ' this array will hold each line of data
afile.TextFieldType = FileIO.FieldType.Delimited
afile.Delimiters = New String() {","}
afile.HasFieldsEnclosedInQuotes = True
' parse the actual file
Do While Not afile.EndOfData
Try
Dim tempPerson As New Person
CurrentRecord = afile.ReadFields
tempPerson.ID = CurrentRecord(0)
tempPerson.Name = CurrentRecord(1)
tempPerson.Age = CurrentRecord(2)
tempPerson.Address = CurrentRecord(3)
result.Add(tempPerson)
Catch ex As FileIO.MalformedLineException
Stop
End Try
Loop
Return result
End Function
只需致电:
Dim MyPersonnel As List(Of Person) = ExtractData("C:\test.csv")
在此之后只需创建一个函数,其中MyPersonnel中的每个Person都将数据插入到数据库中。
仅当您确定数据具有固定格式
时才会有效这里我使用一个类来存储数据,以防你需要修改它或者如果你需要插入它就可以直接为extract函数中的每一行创建一个插入
答案 1 :(得分:1)
这是我一直使用的功能,你可以通过在for循环中插入if来灵活变通: -
Public Function convert_csv_to_data_table(ByVal File As String, ByVal separator As String)
Dim dt As New System.Data.DataTable
Dim firstLine As Boolean = True
If IO.File.Exists(File) Then
Using sr As New StreamReader(File)
While Not sr.EndOfStream
If firstLine Then
firstLine = False
Dim cols = sr.ReadLine.Split(separator)
'down here change the cols types (they are all set as string at the moment)
'however you can change by using if's, eg. if col = "field name" then dt.Columns.Add(New DataColumn(col, GetType(DECIMAL))).
For Each col In cols
dt.Columns.Add(New DataColumn(col, GetType(String)))
Next
Else
Dim data() As String = sr.ReadLine.Split(separator)
dt.Rows.Add(data.ToArray)
End If
End While
End Using
End If
Return dt
End Function
答案 2 :(得分:0)
因此,正如Mederic和Colster先前提到的,我可以简单地使用Schema文件来更改在特定CSV文件上读取值的方式。所以为了做到这一点,知道列在任何上传过程中都保持不变,我创建了一个模式并将列设置为它们各自的值。
Dim strSchema() As String = {"[" & ofdOpenExcelSheet.SafeFileName & "]", "ColNameHeader=True", "Format=CSVDelimited", "Col1=A Text", "Col2=B Text", "Col3=C Text", "Col4=D Text", "Col5=E Integer", "Col6=""F Space"" Decimal", "Col7=""G Space"" Decimal"}
Using outFile As New StreamWriter(Path.GetDirectoryName(fullDir) & Convert.ToString("\Schema.ini"))
For Each line As String In strSchema
outFile.WriteLine(line)
Next
End Using
Dim conn As OleDbConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Path.GetDirectoryName(fullDir) & ";Extended Properties=""Text;HDR=Yes;FMT=Delimited;MaxScanRows=0;IMEX=1"";")
conn.Open()
Dim adp As New OleDbDataAdapter("SELECT * FROM [" & fileName & "]", conn)
adp.Fill(dt)
conn.Close()
' Remove schema since we don't need it.
My.Computer.FileSystem.DeleteFile(Path.GetDirectoryName(fullDir) & Convert.ToString("\Schema.ini"))
答案 3 :(得分:-1)
使用模式文件帮助,这样就可以显式定义每个列类型,而不管内容