最近有個要將資料寫入 CSV 檔案的需求,一般大家對於 CSV 檔案的處理應該就如同處理文字檔的方式一樣,但因為我需要寫入的資料並不是固定的一個類別,而是會因為不同資料處理而會需要將不同類別的資料給寫入到 CSV 檔案裡,像遇到這種需要處理不同類別的狀況時,我比較常看到的就是針對一個類別然後去寫一個相對應的方法去做處理,另外還有看到的就是建立一個很大的方法,在這個方法裡用 switch case 方式先判別進來的資料是哪一種類型,然後再去個別的做處理,其實第二種方法跟第一種方法並沒有什麼分別,不同的地方只在於第一種方法是分散的,而第二種方法是將第一種方法裡分散四處的 method 給集中在一起而已。
我是一個很懶惰的人,對於這樣的需求,我不太喜歡花太多時間去想應該怎麼解決,或是自己動手去寫程式來處理,因為我知道對於處理 CSV 資料的讀寫,一定早就有人去寫好程式,而我所採用的處理 CSV 資料讀寫工具程式就是「CsvHelper」,老早就已經注意到,只是一直沒有專案能夠用上,剛好現在的專案可以讓我實際的應用,所以就在這邊做個簡單的介紹。
CsvHelper - by Josh Close
https://github.com/JoshClose/CsvHelper
為何會使用 CsvHelper 呢?
最主要的原因是操作上並不是相當複雜,而且有相當詳細的說明文件,而且對於類別對應轉換的處理有提供了進階操作的方法與說明,再來就是它有單元測試,近來專案在這些開發原始碼的第三方套件的採用上,是否有提供單元測試,成了我是否應用在專案裡的一個重要考量,並不是有做單元測試就可以,而是也需要考慮到單元測試的質與量,做得足夠也做得越透徹的話,就讓我對於這些第三方的開發原始碼套件能夠越放心使用。
http://joshclose.github.io/CsvHelper/
另外這個套件是可以透過 Nuget 來取得並安裝到專案上,而且可以在更新的 Version History Log 看到,CsvHelper 是一直持續地更新。
http://www.nuget.org/packages/CsvHelper
Step.1 使用 Nuget 加入 CsvHelper
以下的操作示範是使用 LINQPad Premium Edition,LINQPad 的 Developer 與 Premium 這兩個版本都有提供 Nuget 功能,相當方便。
如果是在 Visual Studio 裡使用的話,也是一樣在專案裡透過 Nuget 安裝 CsvHelper。
範例將會使用 Northwind ( 為什麼一直使用 Northwind 呢?之前有人這麼問過,沒什麼原因,就因為他本來就是一個範例資料庫,表格、欄位、關聯什麼都有,我也懶得為每一個範例去建立全新的資料庫與表格,所以就拿現成的來用啦,也可以使用另外一個範例資料庫 AdventureWorks,不過這個就大了些 )。
Step.2 資料寫到 CSV 裡
現在要做的是,將 Northwind 的 Customers 資料給寫入到 CSV 檔案裡,先定義 Customer 類別,
在 StreamWriter 類別裡指定要寫入 CSV 資料的路徑和檔案名稱,然後使用 CsvHelper 的 CsvWriter 類別,從資料庫取得 Customer 資料之後,使用 Automapper 將資料對應轉換到剛才所建立的 Customer 類別,最後使用 CsvWriter 類別的 WriteRecords 方法,將資料寫入到指定的檔案中。
輸出結果如下:
使用 Excel 開啟:
CsvHelper 預設使用「,(逗號)」為分隔字元,預設建立 CSV 檔案及寫入資料時會在第一列寫入對應的欄位名稱(通常就是類別的屬性名稱)。
Step.3 自訂輸出 CSV 欄位名稱
如果想要自訂輸出的欄位名稱,CsvHelper 有提供一個 CsvClassMap<T> 類別,我們可以另外建立一個 Map 類別並且繼承 CsvClassMap<T>,在這個 Map 類別裡去指定欄位要輸出的名稱,如下:
然後在原本的處理寫入資料的程式前,先去註冊要使用的 ClassMap 類別,如此一來輸出的 CSV 檔案的欄位名稱就會是我們另外指定的名稱了,
輸出結果
這一篇先介紹資料寫入到 CSV 檔案的做法,下一篇則是介紹如何使用 CsvHelper 讀取 CSV 檔案。
相關連結:
Github - CsvHelper
https://github.com/JoshClose/CsvHelper
CsvHelper Documentation
http://joshclose.github.io/CsvHelper/
Nuget - CsvHelper
http://www.nuget.org/packages/CsvHelper
以上
沒有留言:
張貼留言