入力文字列を一文字ずつ読み進めていき、
- 「ダブルクォート」がきたら、そのダブルクォートが"閉じる"までの文字列を項目とする
- 「カンマ」がきたら項目を追加
- 「改行」がきたら行を追加
1行は、Queue<string> に格納し、さらに行の集合を Queue に格納しています。
「CSVファイルを読み込んでDataGridに表示」の DataTable GetCsvDataTable(string content) メソッドを以下のように書き換えます。
private DataTable GetCsvDataTable(string content)
{
string text = content.TrimEnd('\r', '\n');
Queue<Queue<string>> lines = new Queue<Queue<string>>();
Queue<string> line = new Queue<string>();
lines.Enqueue(line);
StringBuilder currentToken = new StringBuilder();
bool isInDoublequote = false;
for (int i = 0; i < text.Length; i++)
{
char c = text[i];
if (isInDoublequote)
{
if (c == '"')
{
if ((i + 1 < text.Length && text[i + 1] != '"') || i == text.Length - 1)
{
isInDoublequote = false;
}
else if (i + 1 < text.Length && text[i + 1] == '"')
{
currentToken.Append('"');
i++;
}
}
else
{
currentToken.Append(c);
}
}
else
{
if (c == ',')
{
line.Enqueue(currentToken.ToString());
currentToken.Clear();
}
else if (c == '"')
{
isInDoublequote = true;
}
else if (c == '\r' || c == '\n')
{
line.Enqueue(currentToken.ToString());
if (i + 1 < text.Length && c == '\r' && text[i + 1] == '\n')
{
i++;
}
line = new Queue<string>();
lines.Enqueue(line);
currentToken.Clear();
}
else
{
currentToken.Append(c);
}
}
}
line.Enqueue(currentToken.ToString());
// データテーブルにコピー
DataTable dt = new DataTable();
int columnLength = lines.Peek().Count;
for (int i = 0; i < columnLength; i++)
{
dt.Columns.Add();
}
while (lines.Count != 0)
{
Queue<string> row = lines.Dequeue();
DataRow dr = dt.NewRow();
int count = 0;
while (row.Count != 0)
{
dr[count] = row.Dequeue();
count++;
}
dt.Rows.Add(dr);
}
return dt;
}
0 件のコメント:
コメントを投稿