.net Visual Basic 如何读取 CSV 文件并在数据网格中显示值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1029850/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Visual Basic How do I read a CSV file and display the values in a datagrid?
提问by MarkJ
I'm using VB 2005, how do I open a CSV file and read the columns/rows and display the values in a datagrid?
我正在使用 VB 2005,如何打开 CSV 文件并读取列/行并在数据网格中显示值?
CSV file example: jsmith,[email protected]
CSV 文件示例:jsmith,[email protected]
I then want to perform an action on each row i.e. each user, how would I do this?
然后我想对每一行(即每个用户)执行一个操作,我该怎么做?
I'm a newbie as you can tell but happy to learn.
正如您所知,我是新手,但很高兴学习。
Thanks
谢谢
回答by MarkJ
Use the TextFieldParserthat's built intoVB.NET. Google found me this example
使用TextFieldParser多数民众赞成内置到VB.NET。谷歌给我找到了这个例子
Using MyReader As New Microsoft.VisualBasic.FileIO.TextFieldParser _
("C:\test\info.csv")
'Specify that reading from a comma-delimited file'
MyReader.TextFieldType = FileIO.FieldType.Delimited
MyReader.SetDelimiters(",")
Dim currentRow As String()
While Not MyReader.EndOfData
Try
currentRow = MyReader.ReadFields()
With Me.dgvReport.Rows
.Add(currentRow) 'Add new row to data grid view'
End With
Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
MsgBox("Line " & ex.Message & _
"is not valid and will be skipped.")
End Try
End While
End Using
回答by Bob Mc
Here's a simple solution that uses ADO.Net's ODBC text driver:
这是一个使用 ADO.Net 的 ODBC 文本驱动程序的简单解决方案:
Dim csvFileFolder As String = "C:\YourFileFolder"
Dim csvFileName As String = "YourFile.csv"
'Note that the folder is specified in the connection string,
'not the file. That's specified in the SELECT query, later.
Dim connString As String = "Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=" _
& csvFileFolder & ";Extended Properties=""Text;HDR=No;FMT=Delimited"""
Dim conn As New Odbc.OdbcConnection(connString)
'Open a data adapter, specifying the file name to load
Dim da As New Odbc.OdbcDataAdapter("SELECT * FROM [" & csvFileName & "]", conn)
'Then fill a data table, which can be bound to a grid
Dim dt As New DataTable
da.Fill(dt)
grdCSVData.DataSource = dt
Once filled, you can value properties of the datatable, like ColumnName, to make utilize all the powers of the ADO.Net data objects.
填充后,您可以对数据表的属性(如 ColumnName)进行赋值,以利用 ADO.Net 数据对象的所有功能。
In VS2008 you can use Linq to achieve the same effect.
在 VS2008 中你可以使用 Linq 来达到同样的效果。
回答by Spencer Ruport
Usage:
用法:
Dim reader As New Common.CSVReader("C:\MyFile.txt")
reader.DisplayResults(dgvMyView)
Class:
班级:
Imports System.Windows.Forms
Imports System.IO
Imports System.Text.RegularExpressions
Public Class CSVReader
Private Const ESCAPE_SPLIT_REGEX = "({1}[^{1}]*{1})*(?<Separator>{0})({1}[^{1}]*{1})*"
Private FieldNames As String()
Private Records As List(Of String())
Private ReadIndex As Integer
Public Sub New(File As String)
Records = New List(Of String())
Dim Record As String()
Dim Reader As New StreamReader(File)
Dim Index As Integer = 0
Dim BlankRecord As Boolean = True
FieldNames = GetEscapedSVs(Reader.ReadLine())
While Not Reader.EndOfStream
Record = GetEscapedSVs(Reader.ReadLine())
BlankRecord = True
For Index = 0 to Record.Length - 1
If Record(Index) <> "" Then BlankRecord = False
Next
If Not BlankRecord Then Records.Add(Record)
End While
ReadIndex = -1
Reader.Close()
End Sub
Private Function GetEscapedSVs(Data As String, Optional Separator As String = ",", Optional Escape As String = """") As String()
Dim Result As String()
Dim Index As Integer
Dim PriorMatchIndex As Integer = 0
Dim Matches As MatchCollection = _
Regex.Matches(Data, String.Format(ESCAPE_SPLIT_REGEX, Separator, Escape))
ReDim Result(Matches.Count)
For Index = 0 to Result.Length - 2
Result(Index) = Data.Substring(PriorMatchIndex, Matches.Item(Index).Groups("Separator").Index - PriorMatchIndex)
PriorMatchIndex = Matches.Item(Index).Groups("Separator").Index + Separator.Length
Next
Result(Result.Length - 1) = Data.Substring(PriorMatchIndex)
For Index = 0 To Result.Length - 1
If Regex.IsMatch(Result(Index), String.Format("^{0}[^{0}].*[^{0}]{0}$", Escape)) Then _
Result(Index) = Result(Index).Substring(1, Result(Index).Length - 2)
Result(Index) = Replace(Result(Index), Escape & Escape, Escape)
If Result(Index) Is Nothing Then Result(Index) = ""
Next
GetEscapedSVs = Result
End Function
Public ReadOnly Property FieldCount As Integer
Get
Return FieldNames.Length
End Get
End Property
Public Function GetString(Index As Integer) As String
Return Records(ReadIndex)(Index)
End Function
Public Function GetName(Index As Integer) As String
Return FieldNames(Index)
End Function
Public Function Read() As Boolean
ReadIndex = ReadIndex + 1
Return ReadIndex < Records.Count
End Function
Public Sub DisplayResults(DataView As DataGridView)
Dim col As DataGridViewColumn
Dim row As DataGridViewRow
Dim cell As DataGridViewCell
Dim header As DataGridViewColumnHeaderCell
Dim Index As Integer
ReadIndex = -1
DataView.Rows.Clear()
DataView.Columns.Clear()
For Index = 0 to FieldCount - 1
col = new DataGridViewColumn()
col.CellTemplate = new DataGridViewTextBoxCell()
header = new DataGridViewColumnHeaderCell()
header.Value = GetName(Index)
col.HeaderCell = header
DataView.Columns.Add(col)
Next
Do While Read()
row = new DataGridViewRow()
For Index = 0 to FieldCount - 1
cell = new DataGridViewTextBoxCell()
cell.Value = GetString(Index).ToString()
row.Cells.Add(cell)
Next
DataView.Rows.Add(row)
Loop
End Sub
End Class
回答by Josh Close
Use a library to do the reading for you.
使用图书馆为您阅读。
CsvHelper(a library I maintain) is available via NuGet.
CsvHelper(我维护的一个库)可通过 NuGet 获得。
I'm not familiar with VB, so if anyone wants to change this into VB, please do. Though, it's only a few lines of code.
我不熟悉VB,所以如果有人想把它改成VB,请这样做。虽然,它只有几行代码。
var streamReader = // Create StreamReader to CSV file.
var csvReader = new CsvReader( streamReader );
var myObjects = csvReader.GetRecords<MyObject>();
// You can then databind the myObjects collection to a datagrid.
// If you don't want the whole file, you can read row by row.
var myObject = csvReader.GetRecord<MyObject>();

