在 DataGridView 的引号中导入带有逗号和多行文本的 CSV 文件
Import CSV file with comma and multiline text in quotes in a DataGridView
我正在尝试将 CSV 文件导入到 DataGridView 中,但在尝试导入多行文本时我运行遇到了一些问题。
我要导入的是:
ID;RW;Name;Description;Def;Unit;Min;Max
0;R;REG_INFO;"state of the
machine";0;ms;0;0xFFFF
1;R/W;REG_NUMBER;current number;0;days;0;65,535
导入后应该是这样的:
到目前为止我实现了什么:
Private Sub btnOpen_Click(sender As Object, e As EventArgs) Handles btnOpen.Click
Using ofd As OpenFileDialog = New OpenFileDialog() With {.Filter = "Text file|*.csv"}
If ofd.ShowDialog() = DialogResult.OK Then
Dim lines As List(Of String) = File.ReadAllLines(ofd.FileName).ToList()
Dim list As List(Of Register) = New List(Of Register)
For i As Integer = 1 To lines.Count - 1
Dim data As String() = lines(i).Split(";")
list.Add(New Register() With {
.ID = data(0),
.RW = data(1),
.Name = data(2),
.Description = data(3),
.Def = data(4),
.Unit = data(5),
.Min = data(6),
.Max = data(7)
})
Next
DataGridView1.DataSource = list
End If
End Using
End Sub
但是我 运行 在尝试加载 CSV 时遇到多行文本的一些问题,例如示例中的“机器状态”。
一个例子,使用TextFieldParser class.
(此 class 在 .Net 5 中可用)
The TextFieldParser object provides methods and properties for parsing
structured text files. Parsing a text file with the TextFieldParser is
similar to iterating over a text file, while using the ReadFields
method to extract fields of text is similar to splitting the strings
- 您的数据源是定界(非固定长度)结构,header/fields 值由符号分隔,因此您可以指定
TextFieldType = FieldType.Delimited
- 分隔符不是逗号(
CSV
中的C
),所以您需要将分隔符传递给SetDelimiters()方法。
- 调用 ReadFields() 将每一行提取为字符串数组,代表字段的值(=> 此处不执行任何转换,所有值都作为字符串返回。在中创建您自己的类型转换器以防万一。)
Imports Microsoft.VisualBasic.FileIO
Public Class RegisterParser
Private m_FilePath As String = String.Empty
Private m_delimiters As String() = Nothing
Public Sub New(sourceFile As String, delimiters As String())
m_FilePath = sourceFile
m_delimiters = delimiters
End Sub
Public Function ReadData() As List(Of Register)
Dim result As New List(Of Register)
Using tfp As New TextFieldParser(m_FilePath)
tfp.TextFieldType = FieldType.Delimited
tfp.SetDelimiters(m_delimiters)
tfp.ReadFields()
Try
While Not tfp.EndOfData
result.Add(New Register(tfp.ReadFields()))
End While
Catch fnfEx As FileNotFoundException
MessageBox.Show($"File not found: {fnfEx.Message}")
Catch exIDX As IndexOutOfRangeException
MessageBox.Show($"Invalid Data format: {exIDX.Message}")
Catch exIO As MalformedLineException
MessageBox.Show($"Invalid Data format at line {exIO.Message}")
End Try
End Using
Return result
End Function
End Class
传递 CSV 文件的路径和要使用的分隔符集(此处仅 ;
)。
ReadData()
方法returns一个List(Of Register)
对象,赋值给DataGridView.DataSource
.
DefaultCellStyle.WrapMode 设置为 True
,因此多行文本实际上可以在单元格中换行(否则会被剪裁)。
之后,调用AutoResizeRows(),这样就可以看到换行的文字了。
Dim csvPath = [The CSV Path]
Dim csvParser = New RegisterParser(csvPath, {";"})
DataGridView1.DataSource = csvParser.ReadData()
DataGridView1.Columns("Description").DefaultCellStyle.WrapMode = DataGridViewTriState.True
DataGridView1.AutoResizeRows()
Register
class:
添加了一个接受字符串数组的构造函数。您可以将其更改为 Object()
,然后将转换器添加到 class 以解析并将值转换为另一种类型。
Public Class Register
Public Sub New(ParamArray values As String())
ID = values(0)
RW = values(1)
Name = values(2)
Description = values(3)
Def = values(4)
Unit = values(5)
Min = values(6)
Max = values(7)
End Sub
Public Property ID As String
Public Property RW As String
Public Property Name As String
Public Property Description As String
Public Property Def As String
Public Property Unit As String
Public Property Min As String
Public Property Max As String
End Class
我正在尝试将 CSV 文件导入到 DataGridView 中,但在尝试导入多行文本时我运行遇到了一些问题。
我要导入的是:
ID;RW;Name;Description;Def;Unit;Min;Max
0;R;REG_INFO;"state of the
machine";0;ms;0;0xFFFF
1;R/W;REG_NUMBER;current number;0;days;0;65,535
导入后应该是这样的:
到目前为止我实现了什么:
Private Sub btnOpen_Click(sender As Object, e As EventArgs) Handles btnOpen.Click
Using ofd As OpenFileDialog = New OpenFileDialog() With {.Filter = "Text file|*.csv"}
If ofd.ShowDialog() = DialogResult.OK Then
Dim lines As List(Of String) = File.ReadAllLines(ofd.FileName).ToList()
Dim list As List(Of Register) = New List(Of Register)
For i As Integer = 1 To lines.Count - 1
Dim data As String() = lines(i).Split(";")
list.Add(New Register() With {
.ID = data(0),
.RW = data(1),
.Name = data(2),
.Description = data(3),
.Def = data(4),
.Unit = data(5),
.Min = data(6),
.Max = data(7)
})
Next
DataGridView1.DataSource = list
End If
End Using
End Sub
但是我 运行 在尝试加载 CSV 时遇到多行文本的一些问题,例如示例中的“机器状态”。
一个例子,使用TextFieldParser class.
(此 class 在 .Net 5 中可用)
The TextFieldParser object provides methods and properties for parsing structured text files. Parsing a text file with the TextFieldParser is similar to iterating over a text file, while using the ReadFields method to extract fields of text is similar to splitting the strings
- 您的数据源是定界(非固定长度)结构,header/fields 值由符号分隔,因此您可以指定
TextFieldType = FieldType.Delimited
- 分隔符不是逗号(
CSV
中的C
),所以您需要将分隔符传递给SetDelimiters()方法。 - 调用 ReadFields() 将每一行提取为字符串数组,代表字段的值(=> 此处不执行任何转换,所有值都作为字符串返回。在中创建您自己的类型转换器以防万一。)
Imports Microsoft.VisualBasic.FileIO
Public Class RegisterParser
Private m_FilePath As String = String.Empty
Private m_delimiters As String() = Nothing
Public Sub New(sourceFile As String, delimiters As String())
m_FilePath = sourceFile
m_delimiters = delimiters
End Sub
Public Function ReadData() As List(Of Register)
Dim result As New List(Of Register)
Using tfp As New TextFieldParser(m_FilePath)
tfp.TextFieldType = FieldType.Delimited
tfp.SetDelimiters(m_delimiters)
tfp.ReadFields()
Try
While Not tfp.EndOfData
result.Add(New Register(tfp.ReadFields()))
End While
Catch fnfEx As FileNotFoundException
MessageBox.Show($"File not found: {fnfEx.Message}")
Catch exIDX As IndexOutOfRangeException
MessageBox.Show($"Invalid Data format: {exIDX.Message}")
Catch exIO As MalformedLineException
MessageBox.Show($"Invalid Data format at line {exIO.Message}")
End Try
End Using
Return result
End Function
End Class
传递 CSV 文件的路径和要使用的分隔符集(此处仅 ;
)。
ReadData()
方法returns一个List(Of Register)
对象,赋值给DataGridView.DataSource
.
DefaultCellStyle.WrapMode 设置为 True
,因此多行文本实际上可以在单元格中换行(否则会被剪裁)。
之后,调用AutoResizeRows(),这样就可以看到换行的文字了。
Dim csvPath = [The CSV Path]
Dim csvParser = New RegisterParser(csvPath, {";"})
DataGridView1.DataSource = csvParser.ReadData()
DataGridView1.Columns("Description").DefaultCellStyle.WrapMode = DataGridViewTriState.True
DataGridView1.AutoResizeRows()
Register
class:
添加了一个接受字符串数组的构造函数。您可以将其更改为 Object()
,然后将转换器添加到 class 以解析并将值转换为另一种类型。
Public Class Register
Public Sub New(ParamArray values As String())
ID = values(0)
RW = values(1)
Name = values(2)
Description = values(3)
Def = values(4)
Unit = values(5)
Min = values(6)
Max = values(7)
End Sub
Public Property ID As String
Public Property RW As String
Public Property Name As String
Public Property Description As String
Public Property Def As String
Public Property Unit As String
Public Property Min As String
Public Property Max As String
End Class