2010/07/27

[C#] 利用 OleDb 讀取 csv 檔

透過 OleDb 的方式讀取 csv 檔常會遇到型別轉換的問題.
以機關 OID 為例, "2.16.886.101.20003" 會被轉成 "2.1688"
若要解決這問題,就要參考微軟提供的這個設定檔的說明 (http://msdn.microsoft.com/en-us/library/ms709353.aspx).

  1. 將 Schema.ini 放置於與 csv 檔案相同的目錄中。(注意: 檔名一定要是 Schema.ini )
  2. 撰寫Schema.ini:
    1. 加入關聯的 csv 檔: (例如: [309040000E-20080910.csv] )
    2. 第一行是否為欄位名稱 (True / False): ColNameHeader=True
    3. 設定每一行的分隔符號: 以 Tab 分隔 (Format=TabDelimited), 以 csv 的逗號分隔 (Format=CSVDelimited)
    4. 檔案編碼: (例如: CharacterSet=ANSI)
    5. 各欄位的資料格式設定: Coln ( n 表示順序)=CustomerNumber (欄位名) Text (資料型態) Width 10 (資料長度)
  3. 設定 OldDb 的 ConnectionString: Provider=Microsoft.Jet.OLEDB.4.0;Data Source={csv檔的目錄};Extended Properties='Text;'
    1. Data Source: 這邊要給的是目錄的路徑
    2. Extended Properties: 只需指定 Text, 其他的將會套用設定檔 Schema.ini
  4. 查詢 csv 檔(注意: 查詢的對象是檔名): SELECT * FROM [test.csv]
  5. 指定欄位的方式 (注意: 欄位名是定義在 Schema.ini 中的, 不是在 csv 的第一行欄位名稱): dtTable.Rows[0]["欄位名"]
程式碼如下:
using (OleDbConnection conn = new OleDbConnection(
  @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\csv\;Extended Properties='Text;'"))
{
    DataTable dtTable = new DataTable();
    //讀取csv檔
    OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM [Test.csv]", conn);
    try
    {
        adapter.Fill(dtTable);
    }
    
    catch (Exception ex)
    {
        dtTable = new DataTable();
    }
    this.GridView1.DataSource = dtTable;
    this.GridView1.DataBind();
}
補充 (2009/07/17):
如果是使用 ADO 的方式, 此 Schema.ini 依然有效.
程式參考如下:
Dim objConnection, objRs

Set objConnection = Server.CreateObject("ADODB.Connection")
Set objRs = Server.CreateObject("ADODB.Recordset")

objConnection.Open(
"Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=C:\csv\;Extensions=asc,csv,tab,txt;Persist Security Info=False")

objRs.Open "SELECT * FROM [Test.csv]", objConnection, 3, 3
objRs.MoveFirst
While Not objRs.EOF
    Response.Write objRs.Fields.Item("簡述") & "<br/>"
    objRs.MoveNext
WEnd    
objConnection.Close
這邊的欄位名稱一樣是以 Schema.ini 所定義的為準, 而不是 csv 檔的第一行.

沒有留言: