作品欣赏:
正文:
首先我们来了解一下什么是CSV文件?
CSV文件(Comma-Separated Values),中文叫,逗号分隔值或者字符分割值,其文件以纯文本的形式存储表格数据。该文件是一个字符序列,可以由任意数目的记录组成,记录间以某种换行符分割。每条记录由字段组成,字段间的分隔符是其他字符或者字符串。所有的记录都有完全相同的字段序列,相当于一个结构化表的纯文本形式。
如何打开CSV? 用文本文件、EXcel或者类似与文本文件的都可以打开CSV文件。
为什么要用CSV文件?
上面提到了CSV是纯文本文件,它使数据交换更容易,也更易于导入到电子表格或数据库存储中。说白了就是方便数据在不同的表单软件中方便传输交换,省去了Excel这个大包袱;
那么在VB.NET中如何把DataTable数据转换成CSV文件呢?
上面提到了CSV是纯文本文件,所以我们可以按照输出txt文本文件的方式输出csv文件;只需要在数据之间使用逗号(,)或者tab符分割开即可;
那么问题又来了,如果原始表格数据中包含了逗号(,)怎么办?它是不是也起到了分割作用呢?没错,原文的逗号确实也起到了分割的作用,所以在这个时候我们可以用双引号把原始数据引用起来就可以避免该问题了;
那么那么,怎么那么多那么呢?如果原文中也存在双引号呢?咋办?凉拌呗;当我们遇到这种时候,我们可以把原文中的双引号改成双双引号即可解决问题
举个栗子:
原文:
a,88|b"1|c
csv则变成:
"a,88",b""1,c
直接上VB.NET源代码了,有需要的同学可以直接拿去用(该方法是异步函数,可以避免大表卡顿哦)
''' <summary>
''' DataTable转CSV文件
''' </summary>
''' <param name="dt">DataTable</param>
''' <param name="savepath">CSV文件保存路径</param>
''' <returns></returns>
Public Shared Async Function DataTableToCSV(dt As DataTable, savepath As String) As Task(Of Boolean)
If dt.Rows.Count = 0 Then
Throw New Exception("DataTable不能为空...") ''抛出异常信息
Return False
End If
''---------------------------------------
''异步处理数据
Return Await Task.Run(Async Function()
Dim csvobj As New Text.StringBuilder
''表头
Dim csvhead As New Text.StringBuilder
For Each cl As DataColumn In dt.Columns
Dim headtext As String = cl.ColumnName
headtext = headtext.Replace(""""c, """""") ''替换原文中的双引号
If headtext.Contains(","c) OrElse headtext.Contains(","c) Then
csvhead.Append(""""c).Append(headtext).Append(""",")
Else
csvhead.Append(headtext).Append(","c)
End If
Next
Dim subhead As String = csvhead.ToString.Substring(0, csvhead.ToString.Length - 1)
csvobj.Append(subhead)
csvobj.Append(vbCrLf)
csvhead.Clear()
''主体数据
For i As Integer = 0 To dt.Rows.Count - 1 Step 0
Dim bodytext As New Text.StringBuilder
For j As Integer = 0 To dt.Columns.Count - 1 Step 0
Dim dats As String = dt.Rows(i).Item(j)
dats = dats.Replace(""""c, """""") ''替换原文中的双引号
If dats.Contains(","c) OrElse dats.Contains(","c) Then
bodytext.Append(""""c).Append(dats).Append(""",")
Else
bodytext.Append(dats).Append(","c)
End If
j += 1
Next
Dim subbodytext As String = bodytext.ToString.Substring(0, bodytext.ToString.Length - 1)
csvobj.Append(subbodytext)
csvobj.Append(vbCrLf)
bodytext.Clear()
i += 1
Next
''信息写入CSV文件
Dim CsvRes As String = csvobj.ToString
''验证文件是否打开
Dim FlieVef As Boolean = Await Task.Run(Function()
Try
If IO.File.Exists(savepath) = False Then Return False
Using VefStream As New IO.FileStream(savepath,
IO.FileMode.Open,
IO.FileAccess.Read,
IO.FileShare.None)
Return False
End Using
Catch
Return True
End Try
End Function)
''文件未被打开则输出文件,已打开则抛出异常
If FlieVef = False Then
Using streamObj As New IO.StreamWriter(savepath, False, System.Text.Encoding.UTF8)
streamObj.Write(CsvRes)
streamObj.Close()
End Using
csvobj.Clear()
Else
Throw New Exception("要保存的文件已被其他程序占用,请关闭后继续操作...") ''抛出异常信息
Return False
End If
Return True
End Function)
End Function
使用实列:
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim dt As New DataTable
For i = 0 To 10
dt.Columns.Add("列" & i)
Next
For i = 0 To 100
dt.Rows.Add()
For j = 0 To 10
dt.Rows(i).Item(j) = "行""," & i & "列”“," & j & "VB小源码"
Next
Next
DataGridView1.DataSource = dt
Try
Await DataTableToCSV(dt, "C:\test.csv")
MessageBox.Show("CSV文件已保存到:C:\test.csv")
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
今天就到这了!
最近不知道写点什么,有点子或者需要学点什么东西的同学可以下方留言!