DataTableに入っているデータをCSVファイルに保存したいときに利用できるメソッドを紹介します。
ファイルのエンコーディングも指定できます。
フォームの例はC#のデザイナーファイルを紹介しています。
CSVファイルをDataTableに読み込むサンプルはCSVファイルをDataTableに読み込んで表示するを参考にしてみてください。
Form1.Designer.csの一部
#region Windows フォーム デザイナーで生成されたコード
/// <summary>
/// デザイナー サポートに必要なメソッドです。このメソッドの内容を
/// コード エディターで変更しないでください。
/// </summary>
private void InitializeComponent()
{
this.panel1 = new System.Windows.Forms.Panel();
this.cmbEncoding = new System.Windows.Forms.ComboBox();
this.ckOutputColumnName = new System.Windows.Forms.CheckBox();
this.btnOpen = new System.Windows.Forms.Button();
this.cmbSeparator = new System.Windows.Forms.ComboBox();
this.cmbQuote = new System.Windows.Forms.ComboBox();
this.dataGridView1 = new System.Windows.Forms.DataGridView();
this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
this.btnSave = new System.Windows.Forms.Button();
this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
this.panel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
this.SuspendLayout();
//
// panel1
//
this.panel1.Controls.Add(this.btnSave);
this.panel1.Controls.Add(this.cmbEncoding);
this.panel1.Controls.Add(this.ckOutputColumnName);
this.panel1.Controls.Add(this.btnOpen);
this.panel1.Controls.Add(this.cmbSeparator);
this.panel1.Controls.Add(this.cmbQuote);
this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
this.panel1.Location = new System.Drawing.Point(0, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(745, 42);
this.panel1.TabIndex = 0;
//
// cmbEncoding
//
this.cmbEncoding.FormattingEnabled = true;
this.cmbEncoding.Items.AddRange(new object[] {
"SHIFT_JIS",
"UTF-8",
"EUC-JP"});
this.cmbEncoding.Location = new System.Drawing.Point(330, 13);
this.cmbEncoding.Name = "cmbEncoding";
this.cmbEncoding.Size = new System.Drawing.Size(121, 20);
this.cmbEncoding.TabIndex = 4;
//
// ckOutputColumnName
//
this.ckOutputColumnName.AutoSize = true;
this.ckOutputColumnName.Location = new System.Drawing.Point(475, 14);
this.ckOutputColumnName.Name = "ckOutputColumnName";
this.ckOutputColumnName.Size = new System.Drawing.Size(66, 16);
this.ckOutputColumnName.TabIndex = 3;
this.ckOutputColumnName.Text = "列名あり";
this.ckOutputColumnName.UseVisualStyleBackColor = true;
//
// btnOpen
//
this.btnOpen.Location = new System.Drawing.Point(547, 11);
this.btnOpen.Name = "btnOpen";
this.btnOpen.Size = new System.Drawing.Size(75, 23);
this.btnOpen.TabIndex = 2;
this.btnOpen.Text = "読み込む";
this.btnOpen.UseVisualStyleBackColor = true;
this.btnOpen.Click += new System.EventHandler(this.btnOpen_Click);
//
// cmbSeparator
//
this.cmbSeparator.FormattingEnabled = true;
this.cmbSeparator.Items.AddRange(new object[] {
"カンマ区切り",
"タブ区切り",
"スペース区切り"});
this.cmbSeparator.Location = new System.Drawing.Point(182, 12);
this.cmbSeparator.Name = "cmbSeparator";
this.cmbSeparator.Size = new System.Drawing.Size(121, 20);
this.cmbSeparator.TabIndex = 1;
//
// cmbQuote
//
this.cmbQuote.FormattingEnabled = true;
this.cmbQuote.Items.AddRange(new object[] {
"\"",
"なし"});
this.cmbQuote.Location = new System.Drawing.Point(13, 13);
this.cmbQuote.Name = "cmbQuote";
this.cmbQuote.Size = new System.Drawing.Size(121, 20);
this.cmbQuote.TabIndex = 0;
//
// dataGridView1
//
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.dataGridView1.Location = new System.Drawing.Point(0, 42);
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.RowTemplate.Height = 21;
this.dataGridView1.Size = new System.Drawing.Size(745, 297);
this.dataGridView1.TabIndex = 1;
//
// openFileDialog1
//
this.openFileDialog1.FileName = "openFileDialog1";
//
// btnSave
//
this.btnSave.Location = new System.Drawing.Point(641, 11);
this.btnSave.Name = "btnSave";
this.btnSave.Size = new System.Drawing.Size(75, 23);
this.btnSave.TabIndex = 5;
this.btnSave.Text = "保存する";
this.btnSave.UseVisualStyleBackColor = true;
this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(745, 339);
this.Controls.Add(this.dataGridView1);
this.Controls.Add(this.panel1);
this.Name = "Form1";
this.Text = "Form1";
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.ComboBox cmbSeparator;
private System.Windows.Forms.ComboBox cmbQuote;
private System.Windows.Forms.Button btnOpen;
private System.Windows.Forms.DataGridView dataGridView1;
private System.Windows.Forms.OpenFileDialog openFileDialog1;
private System.Windows.Forms.CheckBox ckOutputColumnName;
private System.Windows.Forms.ComboBox cmbEncoding;
private System.Windows.Forms.Button btnSave;
private System.Windows.Forms.SaveFileDialog saveFileDialog1;
Form1.cs
//dt:データを入れるDataTable
//fileName:ファイル名
//hasHeader:CSVの一行目がカラム名かどうか
//separator:カラムを分けている文字(,など)
//quote:カラムを囲んでいる文字("など)
//replace:クォーテーション文字のデータ内でのエスケープ処理のための文字
//ed:CSVファイルのエンコーディング
private void SaveToCSV(DataTable dt, string fileName, bool hasHeader, string separator, string quote, string replace, Encoding ed)
{
int rows = dt.Rows.Count;
int cols = dt.Columns.Count;
string text;
//保存用のファイルを開く。上書きモードで。
StreamWriter writer = new StreamWriter(fileName, false, ed);
//カラム名を保存するか
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();
}
private void btnSave_Click(object sender, EventArgs e)
{
Encoding ed = null;
string quote = "";
string separator = "";
string replace = "";
//クォーテーションの設定
switch (this.cmbQuote.SelectedIndex)
{
case 0:
//ダブルクォーテーション
quote = "\"";
//エスケープ処理の為の文字
replace = "\"\"";
break;
case 1:
//クォーテーションなし
quote = "";
//エスケープ処理の為の文字だがここでは特に無し
replace = "";
break;
}
//区切り文字の設定
switch (this.cmbSeparator.SelectedIndex)
{
case 0:
//カンマ区切り
separator = ",";
break;
case 1:
//タブ区切り
separator = "\t";
break;
case 2:
//スペース区切り
separator = " ";
break;
}
//ファイルのエンコーディングの設定
switch (this.cmbEncoding.SelectedIndex)
{
case 0:
//SHIFT-JIS
ed = Encoding.GetEncoding("shift_jis");
break;
case 1:
//UTF-8
ed = Encoding.GetEncoding("utf-8");
break;
case 2:
//EUC-JP
ed = Encoding.GetEncoding("euc_jp");
break;
}
if (this.saveFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
SaveToCSV(this._dt, this.saveFileDialog1.FileName, ckOutputColumnName.Checked, separator, quote, replace, ed);
}
}
Form1.vb
'dt:データを入れるDataTable
'fileName:ファイル名
'hasHeader:CSVの一行目がカラム名かどうか
'separator:カラムを分けている文字(,など)
'quote:カラムを囲んでいる文字("など)
'replace:クォーテーション文字のデータ内でのエスケープ処理のための文字
'ed:CSVファイルのエンコーディング
Private Sub SaveToCSV(dt As DataTable, fileName As String, hasHeader As Boolean, separator As String, quote As String, replace As String, ed As Encoding)
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, ed)
'カラム名を保存するか
If hasHeader = True Then
'カラム名を保存する場合
For i As Integer = 0 To cols - 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 i
End If
'データの保存処理
For i As Integer = 0 To rows - 1
For j As Integer = 0 To cols - 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
writer.Write(quote + text + quote + separator)
Else
'最後のレコードなら区切り文字は要らない
writer.WriteLine(quote + text + quote)
End If
Next j
Next i
'ストリームを閉じる
writer.Close()
End Sub
Private Sub btnSave_Click(sender As System.Object, e As System.EventArgs) Handles btnSave.Click
Dim ed As Encoding = Nothing
Dim quote As String = ""
Dim separator As String = ""
Dim replace As String = ""
'クォーテーションの設定
Select Me.cmbQuote.SelectedIndex
Case 0
'ダブルクォーテーション
quote = """"
'エスケープ処理の為の文字
replace = """"""
Case 1
'クォーテーションなし
quote = ""
'エスケープ処理の為の文字だがここでは特に無し
replace = ""
End Select
'区切り文字の設定
Select Me.cmbSeparator.SelectedIndex
Case 0
'カンマ区切り
separator = ","
Case 1
'タブ区切り
separator = "\t"
Case 2
'スペース区切り
separator = " "
End Select
'ファイルのエンコーディングの設定
Select Me.cmbEncoding.SelectedIndex
Case 0
'SHIFT-JIS
ed = Encoding.GetEncoding("shift_jis")
Case 1
'UTF-8
ed = Encoding.GetEncoding("utf-8")
Case 2
'EUC-JP
ed = Encoding.GetEncoding("euc_jp")
End Select
If Me.SaveFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
SaveToCSV(Me._dt, Me.SaveFileDialog1.FileName, ckOutputColumnName.Checked, separator, quote, replace, ed)
End If
End Sub
