2014年4月24日木曜日

[C#]DataTableからCSVファイル生成

DataTable から CSV ファイルを生成する方法を考えてみました。
普通にやるなら、RowのItemを結合して作ると思いますが、それでは面白くない。

DataTable の Column 情報から出力フォーマットを先に作っておいて、Row の ItemArray を配列にしたもので行データを一気に作るという案でやってみました。結構スッキリかけたと思います。

        /// <summary>
        /// データテーブルからCSVファイル出力
        /// </summary>
        /// <param name="table">データテーブル</param>
        /// <param name="filePath">出力ファイルパス</param>
        public void DataTableToCsv(DataTable table, string filePath)
        {
            var columns = table.Columns;
            var formatList = new List<string>();
            for (int i = 0; i < columns.Count; i++)
            {
                // columns[i].DataType で出力対象外の型があれば、formatList.Add("");
                formatList.Add("{" + i + "}");
            }
            var rowFormat = string.Join(",", formatList.ToArray());

            using (var writer = new StreamWriter(filePath, false, Encoding.UTF8))
            {
                // ヘッダ出力する場合は下記をコメントアウト
                //var columnNames = string.Join(",", columns.Cast<DataColumn>().Select(column => column.ColumnName).ToArray());
                //writer.WriteLine(columnNames);
                //writer.Flush();

                foreach (DataRow row in table.Rows)
                {
                    var array = row.ItemArray.Select(item => itemConverter(item, "yyyy-MM-dd HH:mm:ss")).ToArray();

                    writer.WriteLine(string.Format(rowFormat, array));
                    writer.Flush();
                }
            }
        }


        /// <summary>
        /// 値変換
        /// </summary>
        /// <remarks>
        /// 型に応じて出力内容を変換する
        /// </remarks>
        /// <param name="item"></param>
        /// <param name="dateTimeFormat">日時フォーマット</param>
        /// <returns>変換後の値</returns>
        private static object itemConverter(object item, string dateTimeFormat)
        {
            var result = item;
            if (item is byte[])
            {
                result = BitConverter.ToString((byte[])item).Replace("-", "");
            }
            else if (item is string)
            {
                result = "\"" + item + "\"";
            }
            else if (item is DateTime)
            {
                result = "\"" + ((DateTime)item).ToString(dateTimeFormat) + "\"";
            }

            return result;

        }




0 件のコメント:

コメントを投稿