CODE-將CSV檔案內容轉換成ADO.NET DataTable物件
6 |
寫給同事用的工具函數,隨手貼文分享:
/// <summary>
/// 將CSV內容字串轉成DataTable(全部欄位都視為string,有需要請自行轉換), 不支援""包夾格式
/// </summary>
/// <param name="csvContent">整個CSV的內容</param>
/// <param name="firstRowAsHeader">第一列是否為欄位名稱,若無則以C1, C2自動命名</param>
/// <returns></returns>
public static DataTable ConvertCSVtoDataTable(string csvContent,
bool firstRowAsHeader)
{
DataTable t = new DataTable();
using (StringReader sr = new StringReader(csvContent))
{
string line = null;
bool colCreated = false;
while ((line = sr.ReadLine()) != null)
{
string[] p = line.Split(',');
if (!colCreated)
{
int idx = 1;
foreach (string s in p)
{
try
{
t.Columns.Add(
//第一欄是否有欄位名稱? 無則用C1, C2自動編號
firstRowAsHeader ? s : "C" + idx.ToString(),
typeof(string)
);
}
catch (Exception e1)
{
throw new ApplicationException(
"新增欄位失敗! 欄位名稱=" + s + "\n" + e1.ToString());
}
idx++;
}
colCreated = true;
//首欄若為欄名,則不當資料處理
if (firstRowAsHeader) continue;
}
try
{
t.Rows.Add(p);
}
catch (Exception e2)
{
throw new ApplicationException("資料匯入失敗!\n資料=" + line +
"\n錯誤訊息:" + e2.ToString());
}
}
}
return t;
}
private static void test()
{
string csv = "ID,Name,Score\n1,Jeffrey,200\n2,Darkthread,999";
//Or you can read data from file
//string csv = System.IO.File.ReadAllText("B:\\mydata.csv");
DataTable t = ConvertCSVtoDataTable(csv, true);
Debug.WriteLine("RowCount=" + t.Rows.Count);
foreach (DataRow r in t.Rows)
Debug.WriteLine(string.Format("{0}=>{1}", r["Name"], r["Score"]));
csv = "1,Jeffrey,200\n2,Darkthread,999";
t = ConvertCSVtoDataTable(csv, false);
Debug.WriteLine("RowCount=" + t.Rows.Count);
foreach (DataRow r in t.Rows)
Debug.WriteLine(string.Format("{0}=>{1}", r["C2"], r["C3"]));
}
Comments
# by kennyshu
很好奇這種簡單的小工具你同事竟然要麻煩黑大寫?
# by Jeffrey
<p>to kennyshu, 部門裡卧虎藏龍,擅長於其他領域的高手卻未必是.NET專家(但開始逐步轉向.NET是趨勢),我寫五分鐘的Code,可以省卻COBOL前輩(純舉例)盲目摸索兩天半,怎麼算都是宗划算的買賣。(我一直企望有人這種方式幫助我,所以我有能力就這麼做囉~~)</p>
# by 路過的貓
用OLEDB的方式去開EXCEL會比較快嗎? 也可以處理雙引號問題
# by Jeffrey
to 路過的貓, 不知運氣欠佳還是怎樣,遇過好幾次OLEDB解析錯誤的狀況,莫名多出欄位、文字被當數字去前置零... 等等,後來就不怎麼愛它了。
# by 路過的貓
欄位格式的問題,我個人解法是第一行資料都用中文字(欄位名稱) 莫名多出欄位,如果原始檔案(CSV)就有多出多餘的逗點的話會這樣,尤其如果用EXCEL開起來看又看不出所以然 文字被當數字,我是用 1.Extended Properties=Text; 2.搭配設定檔Schema.ini Schema.ini 內容,要跟 CSV 放在同個資料夾 [檔名.csv] Format = CSVDelimited ColNameHeader = False MaxScanRows = 1 (這代表掃描內容時,只採第一行做為欄位格式的判斷) 因為當初找轉檔解決辦法找得一個頭兩個大....... 都沒有一個完美的解法(有些是遇到雙引號內包逗點、雙引號、換行符號時會失常) 有些是文字數字會格式亂跳 最後配出這個折衷方案,請參考....
# by Jeffrey
to 路過的貓, 感謝分享,我記下來了(沙沙沙),衝著您的面子,我下次會再給OLEDB一次機會的。