很多人直覺認為輸出CSV檔是很簡單的事情
不就是一堆由逗號,分隔欄位 再一行一行輸出即可
但若考慮到內容值本身含有, => 剛好與Csv預設用來分隔欄位的符號一樣呢?
或者是內容值本身含有" => 原本期待字串可用" "包覆
當然這些都不難處理 只是處理這種小事很勞民傷財而已
我們可以更優雅的使用ServiceStack來處理
其實ServiceStack還能幫我們優雅的達到以下需求
1. 輸出的欄位名稱 (所以就可以輸出中文欄名、空白、特殊符號...等)
2. 自定Model中哪些欄位要輸出
3. 自訂輸出的時間格式
回到剛剛的例子
實際上會被編碼為
開始!
先到Nuget把ServiceStack安裝
程式碼如下
namespace MySample.Console
{
class Program
{
static void Main(string[] args)
{
var model = new List<MyModel>
{
new MyModel { STR = "A,,,, B", INT = 1, DT = DateTime.Parse("2001/1/1"), NOTE = "程式用得到、但沒要輸出" },
new MyModel { STR = " ' \" ", INT = 2, DT = DateTime.Parse("2001/1/2"), NOTE = "程式用得到、但沒要輸出" },
new MyModel { STR = null, INT = 3, DT = DateTime.Parse("2001/1/3"), NOTE = "程式用得到、但沒要輸出" },
new MyModel { STR = "中文,。", INT = 4, DT = DateTime.Parse("2001/1/4"), NOTE = "程式用得到、但沒要輸出" },
};
ExportObj(model, "D:/temp.csv");
}
public static void ExportObj<T>(IEnumerable<T> obj, string fullPath)
{
//如果想針對DateTime型別有自己想要的輸出格式
JsConfig<DateTime>.SerializeFn = time => new DateTime(time.Ticks).ToString("yyyy/MM/dd HH:mm:ss");
try
{
File.WriteAllText(fullPath, CsvSerializer.SerializeToCsv<T>(obj), new UTF8Encoding(true));
}
catch
{
}
}
}
[DataContract] //當有DataContract時,DataMember才會生效
class MyModel
{
[DataMember(Name = "新名子Str")] //使用 DataMember 自訂最後要輸出到 CSV 中的欄位名稱
public string STR { get; set; }
[DataMember(Name = "空 白 也 可 以")]
public int INT { get; set; }
[DataMember(Name = "這個-也可以")]
public DateTime DT { get; set; }
public string NOTE { get; set; } //不想輸出的欄位,就不要加 DataMember 即可
}
}