DataTable を CSV に変換するにはどうすればいいですか? 質問する

DataTable を CSV に変換するにはどうすればいいですか? 質問する

次のコードが機能しない理由を教えてください。データは csv ファイルに保存されますが、データは分離されていません。すべてのデータが各行の最初のセル内に存在します。

StringBuilder sb = new StringBuilder();

foreach (DataColumn col in dt.Columns)
{
    sb.Append(col.ColumnName + ',');
}

sb.Remove(sb.Length - 1, 1);
sb.Append(Environment.NewLine);

foreach (DataRow row in dt.Rows)
{
    for (int i = 0; i < dt.Columns.Count; i++)
    {
        sb.Append(row[i].ToString() + ",");
    }

    sb.Append(Environment.NewLine);
}

File.WriteAllText("test.csv", sb.ToString());

ありがとう。

ベストアンサー1

次の短いバージョンはExcelで問題なく開きます。問題は末尾のカンマにあったのかもしれません。

.net = 3.5

StringBuilder sb = new StringBuilder(); 

string[] columnNames = dt.Columns.Cast<DataColumn>().
                                  Select(column => column.ColumnName).
                                  ToArray();
sb.AppendLine(string.Join(",", columnNames));

foreach (DataRow row in dt.Rows)
{
    string[] fields = row.ItemArray.Select(field => field.ToString()).
                                    ToArray();
    sb.AppendLine(string.Join(",", fields));
}

File.WriteAllText("test.csv", sb.ToString());

.net >= 4.0

Tim が指摘したように、.net>=4 を使用している場合は、さらに短くすることができます。

StringBuilder sb = new StringBuilder(); 

IEnumerable<string> columnNames = dt.Columns.Cast<DataColumn>().
                                  Select(column => column.ColumnName);
sb.AppendLine(string.Join(",", columnNames));

foreach (DataRow row in dt.Rows)
{
    IEnumerable<string> fields = row.ItemArray.Select(field => field.ToString());
    sb.AppendLine(string.Join(",", fields));
}

File.WriteAllText("test.csv", sb.ToString());

Christian の提案どおり、フィールド内でエスケープされる特殊文字を処理する場合は、ループ ブロックを次のように置き換えます。

foreach (DataRow row in dt.Rows)
{
    IEnumerable<string> fields = row.ItemArray.Select(field => 
      string.Concat("\"", field.ToString().Replace("\"", "\"\""), "\""));
    sb.AppendLine(string.Join(",", fields));
}

最後の提案として、メモリ内に大きなドキュメントが保存されるのを避けるために、ドキュメント全体ではなく csv コンテンツを 1 行ずつ書き込むことができます。

おすすめ記事