VB.NET中从ListView控件导出数据到CSV文件的问题求助
问题说明
使用VB.NET开发时需要将ListView中存储的数值导出为CSV文件,需求如下:
- 导出内容仅保留纯数值,无多余格式字符
- 所有数值排布在CSV的同一列,不要分散到多列/多单元格
当前导出结果显示的是ListBox控件的展示文本而非纯数值,不符合要求。
运行界面截图:
现有导出结果截图:
现有代码
Imports System.IO Imports System.IO.StreamReader Imports System.IO.StreamWriter Imports System.Data.DataSet Public Class Form1 Private Sub startcol_Click(sender As Object, e As EventArgs) Handles startcol.Click Timer1.Enabled = True End Sub Private Sub stopcol_Click(sender As Object, e As EventArgs) Handles stopcol.Click Timer1.Enabled = False End Sub Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick Const MIN As Double = 5.0 Const MAX As Double = 400.0 Const DEC_PLACES As Integer = 2 Dim rnd As New Random Dim list As Integer() '生成介于MIN到MAX之间的随机数,保留DEC_PLACES位小数 Dim dbl As Double = Math.Round(rnd.NextDouble() * (MAX - MIN) + MIN, DEC_PLACES) weight.Text = dbl Dim newItem As New ListViewItem(weight.Text) newItem.SubItems.Add(weight.Text) 'newItem.SubItems.Add(TextBox3.Text) ListBox1.Items.Add(newItem) ListView1.Items.Add(newItem) rowcnt.Text = ListView1.Items.Count End Sub Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Timer1.Enabled = True End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Me.DoSave() End Sub Private Sub DoSave() Dim SFD As New SaveFileDialog() Try With SFD .AddExtension = True .CheckPathExists = True .CreatePrompt = False .OverwritePrompt = True .ValidateNames = True .ShowHelp = True .DefaultExt = "txt" .Filter = _ "CSV Files (*.csv)|*.csv|" & _ "All files|*.*" .FilterIndex = 1 If .ShowDialog() = Windows.Forms.DialogResult.OK Then Me.DoSaveItems(.FileName) End If End With Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.Exclamation, Me.Text) End Try End Sub ' 原有保存方法(存在问题) Private Sub DoSaveItems(ByVal fileName As String) If fileName Is Nothing = False Then If fileName.Length > 0 Then Using writer As New System.IO.StreamWriter(fileName) For Each currentItem As Object In Me.ListView1.Items writer.Write(currentItem.ToString() & ",") Next End Using End If End If End Sub Public Function ExportListViewToCSV(ByVal filename As String, ByVal lv As ListView) As Boolean Try ' 打开输出文件 Dim os As New StreamWriter(filename) ' 写入表头 For i As Integer = 0 To lv.Columns.Count - 1 ' 替换引号避免格式错误 os.Write("""" & lv.Columns(i).Text.Replace("""", """""") & """,") Next os.WriteLine() ' 写入记录 For i As Integer = 0 To lv.Items.Count - 1 For j As Integer = 0 To lv.Columns.Count - 1 os.Write("""" & lv.Items(i).SubItems(j).Text.Replace("""", """""") + """,") Next os.WriteLine() Next os.Close() Catch ex As Exception Return False End Try Return True End Function Public Sub TestExportToCSV() Dim dlg As New SaveFileDialog dlg.Filter = "CSV files (*.CSV)|*.csv" dlg.FilterIndex = 1 dlg.RestoreDirectory = True If dlg.ShowDialog = Windows.Forms.DialogResult.OK Then If ExportListViewToCSV(dlg.FileName, ListView1) Then Process.Start(dlg.FileName) End If End If End Sub Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click 'TestExportToCSV() End Sub End Class
解决方案
原有代码存在两个核心问题:
- 直接调用
currentItem.ToString()会返回ListViewItem的类型描述字符串,而非存储的数值文本 - 用逗号拼接所有数值写在同一行,CSV打开后会分散到同一行的不同列,不符合单列要求
将DoSaveItems方法替换为以下代码即可满足需求:
Private Sub DoSaveItems(ByVal fileName As String) If Not String.IsNullOrEmpty(fileName) Then Using writer As New System.IO.StreamWriter(fileName) For Each currentItem As ListViewItem In Me.ListView1.Items ' 直接读取存储的数值文本,每行写一个值,CSV打开后自动归为同一列 writer.WriteLine(currentItem.Text) Next End Using End If End Sub
如果需要使用ExportListViewToCSV方法实现需求,修改后的代码如下:
Public Function ExportListViewToCSV(ByVal filename As String, ByVal lv As ListView) As Boolean Try Using os As New StreamWriter(filename) ' 遍历所有行只取第一列的纯数值,不需要表头和额外引号 For i As Integer = 0 To lv.Items.Count - 1 os.WriteLine(lv.Items(i).SubItems(0).Text) Next End Using Catch ex As Exception Return False End Try Return True End Function
修改后导出的CSV仅包含纯数值,所有内容都会显示在第一列,无多余格式字符。
内容的提问来源于stack exchange,提问作者dev-ux
相关产品推荐
相关产品推荐

