2

わずかな C# コマンドで (データテーブルの) 単一のデータ行を CSV のような文字列に変換するにはどうすればよいですか。つまり、「value_1;value_2;...;value_n」のような文字列に

4

2 に答える 2

9

単一のクイックアンドダーティDataRow

System.Data.DataRow row = ...;

string csvLine = String.Join(
    CultureInfo.CurrentCulture.TextInfo.ListSeparator,
    row.ItemArray);

カルチャ固有のセパレーターを気にしない場合は、これを実行して完全に変換できますDataTable

public static string ToCsv(System.Data.DataTable table)
{
    StringBuilder csv = new StringBuilder();

    foreach (DataRow row in table.Rows)
        csv.AppendLine(String.Join(";", row.ItemArray));

    return csv.ToString();
}

値のフォーマットを少し処理する必要がある場合のより複雑な例を次に示します (値が単なる数値ではない場合)。

public static string ToCsv(DataTable table)
{
    StringBuilder csv = new StringBuilder();
    
    foreach (DataRow row in table.Rows)
    {
        for (int i = 0; i < row.ItemArray.Length; ++i)
        {
            if (i > 0)
                csv.Append(CultureInfo.CurrentCulture.TextInfo.ListSeparator);
    
            csv.Append(FormatValue(row.ItemArray[i]));
        }
    
        csv.AppendLine();
    }
    
    return csv.ToString();
}

または、LINQ を好む場合 (テーブルが空でないと仮定):

public static string ToCsv(DataTable table, string separator = null)
{
    if (separator == null)
        separator = CultureInfo.CurrentCulture.TextInfo.ListSeparator;

    return table.Rows
        .Cast<DataRow>()
        .Select(r => String.Join(separator, r.ItemArray.Select(c => FormatValue(c)))
        .Aggregate(new StringBuilder(), (result, line) => result.AppendLine(line))
        .ToString();
}

このプライベート関数を使用して値をフォーマットします。これは非常に素朴な実装であり、非プリミティブ型を使用する必要がありTypeConverter(存在する場合は、この素敵なライブラリを参照してください: Universal Type Converter )、必要な場合にのみテキストを引用します ( 2.6 ):

private static string FormatValue(object value)
{
    if (Object.ReferenceEquals(value, null))
        return "";

    Type valueType = value.GetType();

    if (valueType.IsPrimitive || valueType == typeof(DateTime))
        return value.ToString();

    return String.Format("\"{0}\"",
        value.ToString().Replace("\"", "\"\"");
}

CSV
の RFC があっても、多くのアプリケーションはその規則に従わず、特殊なケースを独自の方法で処理します (たとえば、Microsoft Excel はコンマの代わりにロケール リスト区切り記号を使用し、文字列内の改行を処理しません)。標準で要求されているとおり)。

于 2012-06-15T10:17:01.963 に答える
5

これが始まりです:

StringBuilder line = new StringBuilder();
bool first = true;
foreach (object o in theDataRow.ItemArray) {
  string s = o.Tostring();
  if (s.Contains("\"") || s.Contains(",")) {
    s = "\"" + s.Replace("\"", "\"\"") + "\"";
  }
  if (first) {
    first = false;
  } else {
    line.Adppend(',');
  }
  line.Append(s);
}
String csv = line.ToString();

引用符で囲まれた値と区切り記号を含む値を処理します。つまり、引用符または区切り記号を含む値は引用符で囲む必要があり、その中の引用符は二重にしてエスケープする必要があります。

このコードでは、CSV の C が表すカンマを区切り文字として使用していることに注意してください。一部のプログラムでは、セミコロンを使用する方が快適な場合があります。

改善の余地: パディング スペースや改行など、引用をトリガーする他の文字もあります。

注: 現在、CSV ファイルの標準が定義されている場合でも、標準が存在するずっと前に多くのプログラムが開発されたため、それに従うことはめったにありません。通信する必要があるプログラムの特性に適応する必要があります。

于 2012-06-15T10:17:57.723 に答える