型変換を TypeConverter で行うと switch 文とかで分岐させることなくスッキリ書く事ができそうです。いちお、マージする機能もつけておきます。
/// <summary>
/// CSVデータからデータテーブル入力
/// </summary>
/// <remarks>
/// table にはすでにカラムが生成されていること
/// </remarks>
/// <param name="table">OUT データテーブル</param>
/// <param name="filePath">CSVファイルパス</param>
/// <param name="isMerge">マージ有無</param>
public void CsvToDataTable(DataTable table, string filePath, bool isMerge)
{
// 型コンバータ生成
var convList = new List<TypeConverter>();
foreach (DataColumn column in table.Columns)
{
convList.Add(TypeDescriptor.GetConverter(column.DataType));
}
// マージ判定
DataTable importTable;
if (isMerge)
{
importTable = table.Clone();
}
else
{
// マージしない場合は全件削除
foreach (DataRow row in table.Rows)
{
row.Delete();
}
importTable = table;
}
var count = importTable.Columns.Count;
using (var reader = new StreamReader(filePath, Encoding.UTF8))
{
string line;
var rowCount = 0;
while ((line = reader.ReadLine()) != null)
{
rowCount++;
var csvData = line.Split(',');
var row = importTable.NewRow();
for (int cellCount = 0; cellCount < count; cellCount++)
{
try
{
// 型別に変換
var type = importTable.Columns[cellCount].DataType;
if (type == typeof(byte[]))
{
row[cellCount] = HexStringToByteArray(csvData[cellCount]);
}
else if (type == typeof(string) || type == typeof(DateTime))
{
if (csvData[cellCount] != null)
{
row[cellCount] = convList[cellCount].ConvertFrom(csvData[cellCount]);
}
else
{
row.SetField(cellCount, DBNull.Value);
}
}
else
{
if (!string.IsNullOrEmpty(csvData[cellCount]))
{
row[cellCount] = convList[cellCount].ConvertFrom(csvData[cellCount]);
}
else
{
row.SetField(cellCount, DBNull.Value);
}
}
}
catch (Exception e)
{
throw new Exception(string.Format("[行:{0} 列 {1}]{2}", rowCount, cellCount, e.Message));
}
}
importTable.Rows.Add(row);
}
}
if (isMerge)
{
table.Merge(importTable);
}
}
/// <summary>
/// 16進数文字列バイト配列変換
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public byte[] HexStringToByteArray(string data)
{
if (data == null)
throw new ArgumentNullException();
if (data.Length % 2 == 1)
data = "0" + data; // 補正
var list = new List<byte>();
for (int i = 0; i < data.Length - 1; i++, i++)
list.Add(Convert.ToByte(data.Substring(i, 2), 16));
return list.ToArray();
}
関連
- [C#]CSVファイル読み込み
- [Silverlight]CSV出力
- [C#]int型配列->string配列->CSV形式に変換
- [C#]DataTableからCSVファイル生成
- [C#]CSVファイルからDataTable生成
0 件のコメント:
コメントを投稿