DataTableのデータをファイルに保存するときにCSVにして保存したい時がある。そんな時に汎用的に利用できるコードをご紹介しましょう。
CSVファイルを読み込む例はこちらを参考にしてください。
Visual Studio 2010版はこちらを参考にしてみてください。
C#の汎用関数
private void SaveToCSV(DataTable dt, string fileName, bool hasHeader, string separator, string quote, string replace)
{
int rows = dt.Rows.Count;
int cols = dt.Columns.Count;
string text;
//保存用のファイルを開く。上書きモードで。
StreamWriter writer = new StreamWriter(fileName, false, Encoding.GetEncoding("shift_jis"));
//カラム名を保存するか
if (hasHeader)
{
//カラム名を保存する場合
for (int i = 0; i < cols; i++)
{
//カラム名を取得
if (quote != "")
{
text = dt.Columns[i].ColumnName.Replace(quote, replace);
}
else
{
text = dt.Columns[i].ColumnName;
}
if (i != cols - 1)
{
writer.Write(quote + text + quote + separator);
}
else
{
writer.WriteLine(quote + text + quote);
}
}
}
//データの保存処理
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (quote != "")
{
text = dt.Rows[i][j].ToString().Replace(quote, replace);
}
else
{
text = dt.Rows[i][j].ToString();
}
if (j != cols - 1)
{
writer.Write(quote + text + quote + separator);
}
else
{
writer.WriteLine(quote + text + quote);
}
}
}
//ストリームを閉じる
writer.Close();
}
VB.NETの汎用関数
Private dt As New DataTable
'dt:保存すべきデータ
'hasHeader:CSVファイルの1行目にカラム名を入れるか
'separator:カラムとカラムの間の文字(,など)
'quote:カラムを囲む文字
'replace:"などのエスケープの仕方
Private Sub SaveToCSV(ByVal dt As DataTable, ByVal fileName As String, ByVal hasHeader As Boolean, ByVal separator As String, ByVal quote As String, ByVal replace As String)
Dim rows As Integer = dt.Rows.Count
Dim cols As Integer = dt.Columns.Count
Dim text As String
'保存用のファイルを開く。上書きモードで。
Dim writer As StreamWriter = New StreamWriter(fileName, False, Encoding.GetEncoding("shift_jis"))
'カラム名を保存するか
If hasHeader Then
'カラム名を保存する場合
For i As Integer = 0 To cols - 1 Step 1
'カラム名を取得
If quote <> "" Then
text = dt.Columns(i).ColumnName.Replace(quote, replace)
Else
text = dt.Columns(i).ColumnName
End If
If i <> cols - 1 Then
writer.Write(quote + text + quote + separator)
Else
writer.WriteLine(quote + text + quote)
End If
Next
End If
'データの保存処理
For i As Integer = 0 To rows - 1 Step 1
For j As Integer = 0 To cols - 1 Step 1
'クォートが指定されているか
If quote <> "" Then
'指定されている場合エスケープしておく
text = dt.Rows(i)(j).ToString().Replace(quote, replace)
Else
text = dt.Rows(i)(j).ToString()
End If
If j <> cols - 1 Then
'行の最後のカラムでない場合は後ろにまだカラムが続くので、separatorを入れておく
writer.Write(quote + text + quote + separator)
Else
writer.WriteLine(quote + text + quote)
End If
Next j
Next i
'ストリームを閉じる
writer.Close()
End Sub
呼び出し例 C#
private void Button1_Click(object sender, EventArgs e)
{
string quote = "";
string separator = "";
string replace = "";
switch (this.cmbQuote.SelectedIndex)
{
case 0:
//ダブルクォーテーション
quote = "\"";
replace = "\"\"";
break;
case 1:
//シングルクォーテーション
quote = "\'";
replace = "\'\'";
break;
case 2:
//クォーテーションなし
quote = "";
replace = "";
break;
}
switch (this.cmbSeparator.SelectedIndex)
{
case 0:
//カンマ区切り
separator = ",";
break;
case 1:
//タブ区切り
separator = "\t";
break;
case 2:
//スペース区切り
separator = " ";
break;
}
SaveToCSV(this.dt, this.txtFileName.Text, ckOutputColumnName.Checked, separator, quote, replace);
}
呼び出し例 VB.NET
Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
Dim quote As String = ""
Dim separator As String = ""
Dim replace As String = ""
Select Case Me.cmbQuote.SelectedIndex
Case 0
'ダブルクォーテーション
quote = """"
replace = """"""
Case 1
'シングルクォーテーション
quote = "'"
replace = "''"
Case 2
'クォーテーションなし
quote = ""
replace = ""
End Select
Select Case Me.cmbSeparator.SelectedIndex
Case 0
'カンマ区切り
separator = ","
Case 1
'タブ区切り
separator = "\t"
Case 2
'スペース区切り
separator = " "
End Select
SaveToCSV(Me.dt, Me.txtFileName.Text, Me.ckOutputColumnName.Checked, separator, quote, replace)
End Sub
