0%

[DotnetCore]Reader系列-CSV檔案

前提情要

筆者在公司擔任R&D角色一陣子,主要是幫忙製作底層框架,制定分層結構,規範coding style,或者幫忙撰寫底層套件,底層套件部份,大部分都是不同格式的檔案讀取以及寫入;包含CSV檔案,Excel檔案,pdf檔案等主流的,讓筆者有靈感要來寫一下Reader系列,示範一下各式各樣的格式的讀取及寫入吧,這篇就以介紹CSV檔案格式為主。

內容

安裝所需套件,筆者這邊使用CsvHelper這個套件,跟著筆者一步步實作吧。

Demo專案建置

1
2
3
4
5
6
7
8
# 建立資料夾
mkdir reader.demo
# 進入資料夾
cd reader.demo
# 建立console專案
dotnet new console -n reader.demo.console
# 進入console專案
cd reader.demo.console

安裝CsvHelper

1
2
3
4
# 安裝CsvHelper套件
dotnet add package CsvHelper
# 專案使用vscode打開
code .

撰寫CsvExtension

1
2
3
4
5
6
7
8
9
10
11
12
public static class CsvExtension
{
public static List<T> ReadData<T>(string filePath)
{
using (var reader = new StreamReader(filePath))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
var records = csv.GetRecords<T>();
return records.ToList();
}
}
}

準備CSV格式檔案

使用命令列方式建立csv檔案

1
2
3
mkdir Upload
cd Upload
touch Customer.csv

輸入內容

1
2
3
4
顧客ID,顧客信箱
1,abc@gmail.com
2,bcd@gmail.com
3,cde@gmail.com

筆者這邊將該Customer.csv檔案當作範本讀入,因此需要將該檔案輸出至編譯檔案中,Visual Studio中則使用Properties視窗中的Copy選項Always」即可搞定,若使用Visual Studio Code的朋友,可能就沒有地方可以用工具選擇的方式選擇,必須編輯csproj檔案才有辦法。

1
2
3
4
5
<ItemGroup>
<Content Include="Upload/*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>

這邊是定義Upload資料夾下的所有檔案Copy選項定義為Always,即可搞定。

定義Model

接著定義csv檔案對應的class

1
2
3
4
5
6
7
public class Customer
{
[Name("顧客ID")]
public long CustomerId { get; set; }
[Name("顧客信箱")]
public string CustomerEmail { get; set; }
}

可以看到筆者這邊有定義Name Attribute,CSV官網就有提到他使用property屬性的順序,但通常property屬性的順序是不可靠的,建議使用Index或者Name Attribute做定義,才不會亂了秩序。

Client端使用

筆者以簡易的方式示範讀取CSV檔案,因為先前建立的是Console專案,直接於Program.csmain中撰寫

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Program
{
static void Main(string[] args)
{
// 定義執行檔案路徑
var _folder = AppDomain.CurrentDomain.BaseDirectory;
// 使用Path.Combine將csv檔案路徑串起來
var _filePath = Path.Combine(_folder, "Upload", "Customer.csv");
// 使用CsvExtension中的ReadData讀取csv檔案,路徑則串入上面製作的file path
var customers = CsvExtension.ReadData<Customer>(_filePath);
// 使用Newtonsoft.Json套件序列化變成字串印出
System.Console.WriteLine($"[Customers] {JsonConvert.SerializeObject(customers)}");
// 讓終端機停住,看一下上面印出的結果
Console.ReadLine();
}
}

來吧,簡單的使用dotnet run指令來執行

1
2
3
dotnet run
# output
[Customers] [{"CustomerId":1,"CustomerEmail":"abc@gmail.com"},{"CustomerId":2,"CustomerEmail":"bcd@gmail.com"},{"CustomerId":3,"CustomerEmail":"cde@gmail.com"}]

結論

讀完這篇是不是也覺得讀取csv檔案是不是非常簡單,不過老實說要自己寫出這個讀取器也並不難,但是可能需要一段時間校正,若需求本身沒有太多客製化的需求,筆者會選擇不重新造輪子,直接用現成的套件來達成,看專案開發狀況及使用情境了,沒有絕對的好與壞,用得開心,結得了案,基本上都是好事。